Hands-on RNA-seq Analysis from fastq

Sheffield Bioinformatics Core

web : sbc.shef.ac.uk
twitter: [@SheffBioinfCore](https://twitter.com/SheffBioinfCore)
email: bioinformatics-core@sheffield.ac.uk


Tutorial Overview

This tutorial will cover the basics of RNA-seq using Galaxy and Degust; two open-source web-based platforms for the analysis of biological data. You should gain an appreciation of the tasks involved in a typical RNA-seq analysis and be comfortable with the outputs generated by the Bioinformatician.

Using these notes

Sections with this background indicate exercises to be completed during the workshop.

Sections with this background highlight particular shortcuts or other references that might be useful.

Sections with this background give information about potential error messages or might encounter, or problems that might arise in your own data analysis.

More on Galaxy

The official Galaxy page has many tutorials on using the service, and examples of other types of analysis that can be performed on the platform.

Those eventually wanted to perform their own RNA-seq analysis (for example in R), should look out for other courses

Courses on analysing RNA-seq data in R

RNA-seq workflow

Two workflows are possible with RNA-seq data - with the difference being whether one performs an alignment to the reference genome or not.

Recent tools for RNA-seq analysis (e.g. salmon, kallisto) do not require the time-consuming step of whole-genome alignment to be performed, and can therefore produce gene-level counts in a much faster time frame. They not require the creation of large bam files, which is useful if constrained by file space on Galaxy.

(image from Harvard Bioinformatics Core)


Background

Where do the data in this tutorial come from?

The data for this tutorial comes from a Journal of Experimental Medicine paper “Itraconazole targets cell cycle heterogeneity in colorectal cancer”. This study examines the expression profiles of two cell lines in response to treatment with itraconazole.

For this tutorial, we will assume that the wet-lab stages of the experiment have been performed and we are now in the right-hand branch of the workflow. In this tutorial we will demonstrate the steps of Quality assessment, alignment, quantification and differential expression testing.

The fastq data for this experiment were made available on the Sequencing Read Archive (SRA) with accession SRP144496. For the purposes of this workshop we have created a downsampled dataset

The experimental design for the dataset is summarised in the table below.

run name cell_line condition
SRR7108388 HT55_CONT_1 HT55 DMSO
SRR7108389 HT55_CONT_2 HT55 DMSO
SRR7108390 HT55_CONT_3 HT55 DMSO
SRR7108391 HT55_CONT_4 HT55 DMSO
SRR7108392 HT55_ITRA_1 HT55 ITRACONAZOLE
SRR7108393 HT55_ITRA_2 HT55 ITRACONAZOLE
SRR7108394 HT55_ITRA_3 HT55 ITRACONAZOLE
SRR7108395 HT55_ITRA_4 HT55 ITRACONAZOLE
SRR7108396 SW948_CONT_1 SW948 DMSO
SRR7108397 SW948_CONT_2 SW948 DMSO
SRR7108398 SW948_CONT_3 SW948 DMSO
SRR7108399 SW948_CONT_4 SW948 DMSO
SRR7108400 SW948_ITRA_1 SW948 ITRACONAZOLE
SRR7108401 SW948_ITRA_2 SW948 ITRACONAZOLE
SRR7108402 SW948_ITRA_3 SW948 ITRACONAZOLE
SRR7108403 SW948_ITRA_4 SW948 ITRACONAZOLE

Digression: How to download raw sequencing files

The Sequencing Read Archive (SRA) is commonly-used to store the raw data from sequencing experiements and can be accessed through the NCBI website. However, the interface is not particularly friendly and the links to download data and not easy to obtain.

An easier alternative exists in the form of SRA Explorer

The SRA accession (usually found in a paper describing the dataset) can be entered into the Search box, and all the samples belonging to that dataset should be found. Samples of interest can be saved, and upon “checkout” the download links (URLs) will be displayed. A command-line tool such as curl or wget can then be used to download the files locally.

Section 1: Preparation

1. Sign-up to the European Galaxy server

Make sure you check your email to activate your account

Now, use this link to access a special queue. This link will only be active on December 6th.

2. Download the course data

The data for this course have all been shared on a google drive. If you have not done so already, please go to this directory and download the following files

https://drive.google.com/drive/folders/1RSuvl9shAw12Bj77uYSUdWtkZ5ST5EWi?usp=sharing

  • SRR7108388.fastq.gz
  • SRR7108389.fastq.gz
  • SRR7108392.fastq.gz
  • SRR7108393.fastq.gz
  • Homo_sapiens.GRCh38.cdna.all.fa.gz
  • Homo_sapiens.GRCh38.104.gtf.gz
  • tx2gene.txt

3. Import the RNA-seq data for the workshop.

We can going to import the fastq files for this experiment. This is a standard format for storing raw sequencing reads and their associated quality scores. To make the practical quicker, we have downsampled the original fastq files to a quarter of a million reads.

Get Data -> Upload File

You can import the data by:

  1. In the tool panel located on the left, under Basic Tools select Get Data > Upload File. Click on the Choose local file button on the bottom section of the pop-up window.
  2. Navigate to the fastq directory of the zip file that you downloaded from google drive and select these two files from the HT55-DMSO condition.

SRR7108388.fastq.gz SRR7108389.fastq.gz

and these two files are from the HT55 ITRACONAZOLE condition.

SRR7108392.fastq.gz SRR7108393.fastq.gz

also upload the files Homo_sapiens.GRCh38.cdna.all.fa.gz, Homo_sapiens.GRCh38.104.gtf.gz and tx2gene.txt. These are reference files that we will use later.

  1. You should now have these 4 fastq files in your history:
    • SRR7108388.fastq.gz
    • SRR7108389.fastq.gz
    • SRR7108392.fastq.gz
    • SRR7108393.fastq.gz

The annotation files may take a while longer to upload

The .gz at the end of each file name means that it is compressed (like a zip file).

You can upload the other files for extra practice if you wish

Quality assessment with FastQC (Optional)

FastQC is a popular tool from Babraham Institute Bioinformatics Group used for quality assessment of sequencing data. Most Bioinformatics pipelines will use FastQC, or similar tools in the first stage of the analysis. The documentation for FastQC will help you to interpret the plots and stats produced by the tool. A traffic light system is used to alert the user’s attention to possible issues. However, it is worth bearing in mind that the tool is blind to the particular type of sequencing you are performing (i.e. whole-genome, ChIP-seq, RNA-seq), so some warnings might be expected due to the nature of your experiment.

FastQ Quality Control -> FastQC Read Quality reports

  • Select one of the FASTQ files as input and Execute the tool.
  • When the tool finishes running, you should have an HTML file in your History. Click on the eye icon to view the various quality metrics.
  • Run Fastqc on the remaing fastq files, but don’t examine the results just yet.

Question: Do the data seem to be of reasonable quality?

You can use the documentation to help interpret the plots

If poor quality reads towards the ends of reads are considered to be a problem, or there is considerable adapter contamination, we can employ various tools to trim our data.

However, a recent paper demonstrated that read trimming is no longer required prior to alignment:- https://www.biorxiv.org/content/10.1101/833962v1

If you also suspect contamination by another organism, or rRNA present in your data, you can use the sortMeRNA tool to remove this artefact.

Combining QC reports

It can be quite tiresome to click through multiple QC reports and compare the results for different samples. It is useful to have all the QC plots on the same page so that we can more easily spot trends in the data.

The multiqc tool has been designed for the tasks of aggregating qc reports and combining into a single report that is easy to digest.

FASTQ Quality Control -> Multiqc

Under Which tool was used generate logs? Choose fastqc and select the RawData output from the fastqc run on each of your bam files.

Question: Repeat the FastQC analysis for the remaining fastq files and combine the reports with multiQC. Do the fastq files seem to have consistently high-quality?

Section 2: Quantification

We can align our RNA-seq reads to a reference genome, and then overlap with know gene coordinates, but many prefer to align directly to the transcriptome sequences using a method such as salmon or kallisto. We will demonstrate the salmon protocol.

Obtaining the files for salmon

  1. cDNA fasta file

This file has been provided in the google drive folder and should have been uploaded to your Galaxy history.

However, it is useful to know where this file came from in case you are not working with Human data. The file was obtained from Ensembl by clicking on the cDNA (FASTA) link for the appropriate organism (Human).

On the next screen, Right-click to save the .cdna.all.fa.gz to your computer

  1. Transcript mapping file

By default, salmon will produce counts for each transcript. This might be what we want, but for most standard analyses it is preferable to work at the gene-level. We therefore have to tell salmon how the transcripts in the cDNA file relate to known genes. Such a file can be obtained from biomart.

  • Select the Ensembl genes (104) database
  • Select the dataset Human genes (GRCh38.13)
  • In Attributes, click the “+” button next to GENE and select Transcript stable ID version and Gene stable ID. Make sure the order on the left-hand panel is Transcript stable ID version, followed by Gene stable ID. This will affect the column order in the file. You can tick / untick the IDs to make sure the order is correct.

  • Click the Results button in the top left corner to see a preview of the results. Clicking the Go button will export the results to a file

It is important that the file downloaded from Biomart is edited so that the column headings do not contain any spaces. You can do this in a text editor. The edited file should look like this.

It is important to make sure the version number of your transcript file and the biomaRt dataset are the same, otherwise some of the steps downstream might not work as expected.

If you have problems, this mapping file is also provided in the google drive as tx2gene.txt.

  1. Annotation file (optional)

The Ensembl gene IDs are not particularly memorable, so it would be highly beneficial to have other annotations at hand to help us interpret the data downstream. We can use the biomart website again to produce a table to downstream intrepretation.

This time, select only the Gene Stable ID tickbox in the GENE box. Expand the EXTERNAL panel by clicking the “+” next to EXTERNAL, and select HGNC symbol and NCBI gene (formerly Entrezgene) ID

salmon configuration and running

RNA Analysis -> Salmon quant

  • Select the Homo_sapiens_GRCh38.cdna.all.fa.gz file as the Transcripts fasta file
  • Select all your uploaded fastq files as your Data Input FASTQ/FASTA file
  • Scroll down to File containing a mapping of transcripts to genes and select the tx2gene.txt file

Two jobs will now be queued for each sample fastq file. The Quantification output will contain transcript-level data, and the Gene Quantification output will be at the gene-level. We should expect the number of lines in the Gene Quantification file to be substantially less. If not, you will need to check that your transcript mapping file was correct.

The Gene Quantification output from each sample comprises the following columns (taken from the salmon documentation)

  • Name — This is the name of the target transcript provided in the input transcript database (FASTA file).
  • Length — This is the length of the target transcript in nucleotides.
  • EffectiveLength — This is the computed effective length of the target transcript. It takes into account all factors being modeled that will effect the probability of sampling fragments from this transcript, including the fragment length distribution and sequence-specific and gc-fragment bias (if they are being modeled).
  • TPM — This is salmon’s estimate of the relative abundance of this transcript in units of Transcripts Per Million (TPM). TPM is the recommended relative abundance measure to use for downstream analysis.
  • NumReads — This is salmon’s estimate of the number of reads mapping to each transcript that was quantified. It is an “estimate” insofar as it is the expected number of reads that have originated from each transcript given the structure of the uniquely mapping and multi-mapping reads and the relative abundance estimates for each transcript.

Note that we are using a downsampled dataset, so the majority of NumReads will be zero.

Create a count matrix

Methods for detecting differential expression are likely to want data in the form of a table; where every row is a different gene and each column is a unique biological sample. Before we can proceed we will therefore need to merge our salmon results into a single output. This can be down using the Salmon quantmerge tool

RNA Analysis -> Salmon quantmerge

Use the +Insert Quant file and names button repeatedly to select each of your Gene Quantification outputs. The One-word sample names text box can be used to create a shorter column name for each output.

Once all the Gene Quantification files have been selected the drop-down menu under Columns should be changed from Length to NumReads.

After the tool has finished you should have a table with

Adding extra annotation to results

Text Manipulation -> Join two files

  • 1st file: Column Join on data….
  • Column to use from 1st file: Column 1
  • 2nd file: result from annotateMyIDs on data…
  • Column to use from 2nd file: Column 1

(Optional) Alternative workflow involving genome alignment

If time allows, we will also follow this section

The workflow that people used for many years is summarised in this image from Ting-you Wang’s RNA-seq data analysis page, and may still be preferable if your analysis doesn’t just call for gene-level counts.

Mapping -> HISAT2

1. Map/align the reads with HISAT2 to the hg38 reference genome

In the left tool panel menu, under NGS Analysis, select Mapping > HISAT2 and set the parameters as follows:

  • Is this single-end or paired-end data? Single-end (as individual datasets)
  • FASTQ file
    (Click on the multiple datasets icon and select all four of the FASTQ files)
    • SRR7108388.fastq.gz
    • SRR7108389.fastq.gz
    • SRR7108392.fastq.gz
    • SRR7108393.fastq.gz
  • Source for the reference genome Use built-in genome
  • Select a reference genome: Human Dec 2013. (GRCh38/hg38) (hg38)
  • Use defaults for the other fields
  • Execute

Quantification (Counting reads in features)

In order to test for differential expression, we need to count up how many times each “feature” is observed in each sample. The goal of such operations is to produce a count table such as that shown below. We can then apply statistical tests to these data

HTSeq-count creates a count matrix using the number of the reads from each bam file that map to the genomic features. For each feature (a gene for example) a count matrix shows how many reads were mapped to this feature.

Various rules can be used to assign counts to features

To obtain the coordinates of each gene, we can use the UCSC genome browser which is integrated into Galaxy.

Obtaining gene coordinates

Ensembl

Counting reads in genes

RNA Analysis > htseq-count

  1. Use HTSeq-count to count the number of reads for each feature.
    In the left tool panel menu, under NGS Analysis, select NGS Analysis > htseq-count and set the parameters as follows:
    • Aligned SAM/BAM file
      (Select one of four bam files, or all four using the multiple datasets option)
    • GFF file UCSC Main on Mouse:ncbiRefSeq (genome)
    • Use defaults for the other fields
    • Execute
  2. Repeat for the remaining bam files if running on each bam separately.
  3. To make things easier to track, rename the ht-seq output for each sample to contain the corresponding sample name (e.g. SRR1552444.htseq). Do not rename the outputs that have “(no feature)” in their name

Create a count matrix

The htseq tool is designed to produce a separate table of counts for each sample. This is not particularly useful for other tools such as Degust (see next section) which require the counts to be presented in a data matrix where each row is a gene and each column is a particular sample in the dataset.

Collection Operations -> Column Join on Collections

  • In the Tabular Files section, select the ht-seq count files from your history SRR1552444.htseq, SRR1552450, etc… Holding the CTRL key allows multiple files to be selected
  • Keep Identifier column as 1

Differential Expression using Degust

Differential expression is possible using Galaxy using the DESeq2 tool (for example). However, our particular recommendation is to use Degust for a more interactive experience. For this section, we will be using counts generated on the full dataset, rather than the downsampled data analysed in the previous section. These counts are available in the file GSE114013_salmon_counts.csv.

Differential expression

The term differential expression was first used to refer to the process of finding statistically significant genes from a microarray gene expression study.

Such methods were developed on the premise that microarray expression values are approximately normally-distributed when appropriately transformed (e.g. by using a log\(_2\) transformation) so that a modified version of the standard t-test can be used. The same test is applied to each gene under investigation yielding a test statistic, fold-change and p-value. Similar methods have been adapted to RNA-seq data to account for the fact that the data are count-based and do not follow a normal distribution.

http://degust.erc.monash.edu/

Degust is a web tool that can analyse the counts files produced in the step above, to test for differential gene expression. It offers and interactive view of the differential expression results

The input file is a count matrix where each row is a measured gene, and each column is a different biological sample. Within the tool we can configure which samples belong to the different biological groups of interest.

Read counts have to be normalised first prior to differential expression testing. There are two main biases that need to be accounted for:-

  • size of gene
    • longer genes will have more reads assigned to them
  • library size
    • a sample that is sequenced to a higher depth will receive more reads

However, R-based methods such as edgeR (implemented in Degust) and DESeq2 have their own method of normalising counts. You will probably encounter other methods of normalising RNA-seq reads such as RPKM, CPM, TPM etc. This blog provides a nice explanation of the current thinking. As part of the Degust output, you have the option of downloading normalised counts in various formats. Some other online visualisation tools require normalised counts as input, so it is good to have these to-hand.

Uploading the count matrix to Degust

  • From the main degust page, click Upload your counts file
  • Click on Browse
  • Select the location of the file GSE114013_salmon_counts.csv, and click Open.
  • Click Upload
  • A Configuration page will appear.

  • For Name type “GSE114013” (or whatever you want to call the analysis)
  • For Info columns select SYMBOL
  • Click Add condition
    • Referring to the experiment design (below), select the DMSO samples and call the condition DMSO
    • Repeat for the ITRACONAZOLE samples
  • Save the settings and then View the results
run name cell_line condition
SRR7108388 HT55_CONT_1 HT55 DMSO
SRR7108389 HT55_CONT_2 HT55 DMSO
SRR7108390 HT55_CONT_3 HT55 DMSO
SRR7108391 HT55_CONT_4 HT55 DMSO
SRR7108392 HT55_ITRA_1 HT55 ITRACONAZOLE
SRR7108393 HT55_ITRA_2 HT55 ITRACONAZOLE
SRR7108394 HT55_ITRA_3 HT55 ITRACONAZOLE
SRR7108395 HT55_ITRA_4 HT55 ITRACONAZOLE
SRR7108396 SW948_CONT_1 SW948 DMSO
SRR7108397 SW948_CONT_2 SW948 DMSO
SRR7108398 SW948_CONT_3 SW948 DMSO
SRR7108399 SW948_CONT_4 SW948 DMSO
SRR7108400 SW948_ITRA_1 SW948 ITRACONAZOLE
SRR7108401 SW948_ITRA_2 SW948 ITRACONAZOLE
SRR7108402 SW948_ITRA_3 SW948 ITRACONAZOLE
SRR7108403 SW948_ITRA_4 SW948 ITRACONAZOLE

Overview of Degust sections

  • Top black panel with Configure settings at right.
  • Left: Conditions: DMSO and ITRACONAZOLE.
  • Top centre: Plots, with options at right.
  • When either of the expression plots are selected, a heatmap appears below.
  • A table of genes (or features); expression in treatment relative to control (Treatment column); and significance (FDR column).

(Not that the screenshots are for illustration purposes and taken from a different dataset to that being analysed in the tutorial)

MA-plot

Each dot shows the change in expression in one gene.

  • The average expression (over both condition and treatment samples) is represented on the x-axis.
    • Plot points should be symmetrical around the x-axis.
    • We can see that many genes are expressed at a low level, and some are highly expressed.
  • The fold change is represented on the y axis.
    • If expression is significantly different between batch and chem, the dots are red. If not, they are blue. (In Degust, significant means FDR <0.05).
    • At low levels of gene expression (low values of the x axis), fold changes are less likely to be significant.

Click on the dot to see the gene name.

Parallel coordinates and heatmap

Each line shows the change in expression in one gene, between control and treatment.

  • Go to Options at the right.
    • For FDR cut-off set at 0.001.
    • This is a significance level (an adjusted p value). We will set it quite low in this example, to ensure we only examine key differences.
  • Look at the Parallel Coordinates plot. There are two axes:
    • Left: Control: Gene expression in the control samples. All values are set at zero.
    • Right: Treatment Gene expression in the treatment samples, relative to expression in the control.
  • The blocks of blue and red underneath the plot are called a heatmap.
    • Each block is a gene. Click on a block to see its line in the plot above.
    • Look at the row for the chem. Relative to batch, genes expressed more are red; genes expressed less are blue.

Table of genes

Table of genes

  • gene_id: names of genes. Note that gene names are sometimes specific to a species, or they may be only named as a locus ID (a chromosomal location specified in the genome annotation).
  • FDR: False Discovery Rate. This is an adjusted p value to show the significance of the difference in gene expression between two conditions. Click on column headings to sort. By default, this table is sorted by FDR.
  • basal and luminal: log2(Fold Change) of gene expression. The default display is of fold change in the treatment relative to the control. Therefore, values in the batch column are zero. This can be changed in the Options panel at the top right.
    • In some cases, a large fold change will be meaningful but in others, even a small fold change can be important biologically.

The table can be sorted according to any of the columns (e.g. fold-change or p-value)

Download and R code

Above the genes table is the option to download the results of the current analysis to a csv file. You can also download the R code required to reproduce the analysis by clicking the Show R code box underneath the Options box.

Plots such as the MDS, MA and heatmap can also be exported by right-clicking on the plot.

MDS plot

This is a multidimensional scaling plot which represents the variation between samples. It is a similar concept to a Principal Components Analysis (PCA) plot. The x-axis is the dimension with the highest magnitude. In a standard control/treatment setup, samples should be split along this axis. A desirable plot is shown below:-

Exercise

Question: It seems that the differential expression analysis is detecting lots of genes. However, does this tell the whole story about the dataset? What do you think is the main factor separating samples on the x-axis, and thus explaining the most variation in the data?

Modifying the analysis

We will now repeat the analysis, but only for samples from the HT55 cell-line. The correct configuration for this analysis is shown below:-

Exercise: How many genes are differentially-expressed with an FDR < 0.05 and abs logFC > 1. Download this file and rename it to HT55.ITRACONAZOLE_vs_DMSO.csv.

Exercise: Rest the FDR cut-off and abs LogFC cutoffs back to default and download the file and rename to background.csv. We will use this later.

Exercise: Repeat the analysis for SW948 samples and download the table of differentially-expressed results (same FDR and log fold-change) to SW948.ITRACONAZOLE_vs_DMSO.csv

File Downloads

If you didn’t manage to complete these analyses, you can download the files from here by right-clicking on each link and selecting “Save Link as” (or equivalent). They are also available in the course google drive.

Overlapping Gene Lists

We might sometimes want to compare the lists of genes that we identify using different methods, or genes identified from more than one contrast. In our example dataset we can compare the genes in the contrast of ITRACONAZOLE vs DMSO in HT55 and SW948 cells

The website venny provides a really nice interface for doing this.

  • Open both your HT55: ITRACONAZOLE vs DMSO and SW948: ITRACONAZOLE vs DMSO results files in Excel
  • Go to the venny website
  • Copy the names of genes with adjusted p-value less than 0.05 in the HT55 analysis into the List 1 box on the venny website. List 1 can be renamed to HT55
    • You can select all entries in a column with the shortcut CTRL + SPACE
  • Copy the names of genes with adjusted p-value less than 0.05 in the SW948 analysis into the List 2 box on the venny website. List 2 can be renamed to SW948
  • venny should now report the number of genes found in each list, the size of the intersection, and genes unique to each method

Refined analysis

The final analysis we will perform is to include all the samples, but correct for the differences in cell-line. This is achieved by telling Degust about the hidden factors in our dataset. The hidden factor in this dataset is whether the sample is from the HT55 or SW948 samples. However, we only need to specify which samples are from HT55. Other hidden factors you might need to include could be (depending on the MDS plot) :-

  • sample batch
  • gender

See below for the correct configuration to include the hidden factors.

Enrichment and pathways analysis

In the early days of microarray analysis, people were happy if they got a handful of differentially-expressed genes that they could validate or follow-up. However, with later technologies (and depending on the experimental setup) we might have thousands of statistically-significant results, which no-one has the time to follow-up. Also, we might be interested in pathways / mechanisms that are altered and not just individual genes.

In this section we move towards discovering if our results are biologically significant. Are the genes that we have picked statistical flukes, or are there some commonalities.

There are two different approaches one might use, and we will cover the theory behind both. The distinction is whether you are happy to use a hard (and arbitrary) threshold to identify DE genes.

Over-representation analysis

“Threshold-based” methods require defintion of a statistical threshold to define list of genes to test (e.g. FDR < 0.01). Then a hypergeometric test or Fisher’s Exact test generally used. They are typically used in situations where plenty of DE genes have been identified, and people often use quite relaxed criteria for identifying DE genes (e.g. raw rather than adjusted p-values or FDR value)

The question we are asking here is;

“Are the number of DE genes associated with Theme X significantly greater than what we might expect by chance alone?”

We can answer this question by knowing

  • the total number of DE genes
  • the number of genes in the gene set (pathway or process)
  • the number of genes in the gene set that are found to be DE
  • the total number of tested genes (background)

The formula for Fishers exact test is;

\[ p = \frac{\binom{a + b}{a}\binom{c +d}{c}}{\binom{n}{a +c}} = \frac{(a+b)!(c+d)!(a+c)!(b+d)!}{a!b!c!d!n!} \]

with:-

is DE Not DE Row Total
In Gene Set a b a + b
Not in Gene Set c d c + d
Column Total a + c b + d a + b + c + d = n

In this first test, our genes will be grouped together according to their Gene Ontology (GO) terms:- http://www.geneontology.org/

Using GOrilla

There are several popular online tools for performing enrichment analysis

We will be using the online tool GOrilla to perform the pathways analysis as it is particularly straightforward. It has two modes; the first of which accepts a list of background and target genes.

  1. Go to http://cbl-gorilla.cs.technion.ac.il/
  2. Choose Organism: Homo Sapiens
  3. Choose running mode: Two unranked lists of genes
  4. Paste the gene symbols corresponding to DE genes in SW948: ITRACONAZOLE vs DMSO into the Target set.
  • The shortcut CTRL + SPACE will let you select an entire column
  1. Paste the gene symbols from the Background set into the other box. This should be the names of all genes present in the Background file. i.e. all genes that were tested.
  2. Choose an Ontology: Process
  3. Under advanced options, tick Output results in Microsoft Excel format
  4. Search Enriched GO terms

You should be presented with a graph of enriched GO terms showing the relationship between the terms. Each GO term is coloured according to its statistical significance.

Below the figure is the results table. This links to more information about each GO term, and lists each gene in the category that was found in your list. The enrichment column gives 4 numbers that are used to determine enrichment (similar to the Fisher exact test we saw earlier)

  • N, total number of genes (should be the same in all rows)
  • B, total number of genes annotated with the GO term
  • n, total number of genes that were found in the list you uploaded (same for all rows)
  • b, number of genes in the list you uploaded that intersect with this GO term

Exercise: Repeat the GOrilla to find enriched pathways in the HT55: ITRACONAZOLE vs DMSO analysis. What do you notice?

Threshold-free analysis

This type of analysis is popular for datasets where differential expression analysis does not reveal many genes that are differentially-expressed on their own. Instead, it seeks to identify genes that as a group have a tendancy to be near the extremes of the log-fold changes. The results are typically presented in the following way.

As such, it does not rely on having to impose arbitrary cut-offs on the data. Instead, we need to provide a measure of the importance of each gene such as it’s fold-change. These are then used the rank the genes.

The Broad institute has made this analysis method popular and provides a version of GSEA that can be run via a java application. However, the application can be a bit fiddly to run, so we will use the GeneTrail website instead

  • Open the file background.csv in Excel and delete all columns except the SYMBOL and ITRA column.
  • Go to the GeneTrail website, and select Transcriptomics from the front page
  • Select the Paste the content of a text file in a tabular format option and the contents of your modified excel file into the box. Do not paste the column headings
  • Click Upload

Hopefully it should recognise your input without any errors, and on the next screen the Set-level statistic should be automatically set to GSEA

If your data does not get uploaded, double-check that the column heading ITRA has not been pasted into the text box

To make the analysis run fast, you can de-select the GO pathways (biological processes, molecular function and cellular compartment)

LS0tCnRpdGxlOiAiUk5BLXNlcSB0dXRvcmlhbCIKYXV0aG9yOiAiTWFyayBEdW5uaW5nIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgY3NzOiBzdHlsZXNoZWV0cy9zdHlsZXMuY3NzCiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCgoKIyBIYW5kcy1vbiBSTkEtc2VxIEFuYWx5c2lzIGZyb20gZmFzdHEKCgojIyMgU2hlZmZpZWxkIEJpb2luZm9ybWF0aWNzIENvcmUKPGltZyBzcmM9Im1lZGlhL2xvZ28tc20ucG5nIiBhbGlnbj1yaWdodD4KCndlYiA6IFtzYmMuc2hlZi5hYy51a10oaHR0cHM6Ly9zYmMuc2hlZi5hYy51aykgIAp0d2l0dGVyOiBbQFNoZWZmQmlvaW5mQ29yZV0oaHR0cHM6Ly90d2l0dGVyLmNvbS9TaGVmZkJpb2luZkNvcmUpICAKZW1haWw6IFtiaW9pbmZvcm1hdGljcy1jb3JlQHNoZWZmaWVsZC5hYy51a10oYmlvaW5mb3JtYXRpY3MtY29yZUBzaGVmZmllbGQuYWMudWspCgotLS0tLQoKIyMgVHV0b3JpYWwgT3ZlcnZpZXcKClRoaXMgdHV0b3JpYWwgd2lsbCBjb3ZlciB0aGUgYmFzaWNzIG9mIFJOQS1zZXEgdXNpbmcgR2FsYXh5IGFuZCBEZWd1c3Q7IHR3byBvcGVuLXNvdXJjZSB3ZWItYmFzZWQgcGxhdGZvcm1zIGZvciB0aGUgYW5hbHlzaXMgb2YgYmlvbG9naWNhbCBkYXRhLiBZb3Ugc2hvdWxkIGdhaW4gYW4gYXBwcmVjaWF0aW9uIG9mIHRoZSB0YXNrcyBpbnZvbHZlZCBpbiBhIHR5cGljYWwgUk5BLXNlcSBhbmFseXNpcyBhbmQgYmUgY29tZm9ydGFibGUgd2l0aCB0aGUgb3V0cHV0cyBnZW5lcmF0ZWQgYnkgdGhlIEJpb2luZm9ybWF0aWNpYW4uCgoKIyMgVXNpbmcgdGhlc2Ugbm90ZXMKCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4KU2VjdGlvbnMgd2l0aCB0aGlzIGJhY2tncm91bmQgaW5kaWNhdGUgZXhlcmNpc2VzIHRvIGJlIGNvbXBsZXRlZCBkdXJpbmcgdGhlIHdvcmtzaG9wLgo8L2Rpdj4KCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KU2VjdGlvbnMgd2l0aCB0aGlzIGJhY2tncm91bmQgaGlnaGxpZ2h0IHBhcnRpY3VsYXIgc2hvcnRjdXRzIG9yIG90aGVyIHJlZmVyZW5jZXMgdGhhdCBtaWdodCBiZSB1c2VmdWwuCjwvZGl2PgoKPGRpdiBjbGFzcz0id2FybmluZyI+ClNlY3Rpb25zIHdpdGggdGhpcyBiYWNrZ3JvdW5kIGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgcG90ZW50aWFsIGVycm9yIG1lc3NhZ2VzIG9yIG1pZ2h0IGVuY291bnRlciwgb3IgcHJvYmxlbXMgdGhhdCBtaWdodCBhcmlzZSBpbiB5b3VyIG93biBkYXRhIGFuYWx5c2lzLgo8L2Rpdj4KCiMjIyBNb3JlIG9uIEdhbGF4eQoKVGhlIG9mZmljaWFsIEdhbGF4eSBwYWdlIGhhcyBtYW55IFt0dXRvcmlhbHNdKGh0dHBzOi8vZ2FsYXh5cHJvamVjdC5vcmcvbGVhcm4vKSBvbiB1c2luZyB0aGUgc2VydmljZSwgYW5kIGV4YW1wbGVzIG9mIG90aGVyIHR5cGVzIG9mIGFuYWx5c2lzIHRoYXQgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGUgcGxhdGZvcm0uCgpUaG9zZSBldmVudHVhbGx5IHdhbnRlZCB0byBwZXJmb3JtIHRoZWlyIG93biBSTkEtc2VxIGFuYWx5c2lzIChmb3IgZXhhbXBsZSBpbiBSKSwgc2hvdWxkIGxvb2sgb3V0IGZvciBvdGhlciBjb3Vyc2VzCgojIyMgQ291cnNlcyBvbiBhbmFseXNpbmcgUk5BLXNlcSBkYXRhIGluIFIKCi0gW1NoZWZmaWVsZCBCaW9pbmZvcm1hdGljcyBDb3JlXShodHRwczovL3NiYy5zaGVmLmFjLnVrL3RyYWluaW5nL3JuYS1zZXEtaW4tci0yMDIwLTAyLTEzLykKLSBbTW9uYXNoIEJpb2luZm9ybWF0aWNzIFBsYXRmb3JtXShodHRwOi8vbW9uYXNoYmlvaW5mb3JtYXRpY3NwbGF0Zm9ybS5naXRodWIuaW8vUk5Bc2VxLURFLWFuYWx5c2lzLXdpdGgtUi8pCgoKIyMgUk5BLXNlcSB3b3JrZmxvdwoKVHdvIHdvcmtmbG93cyBhcmUgcG9zc2libGUgd2l0aCBSTkEtc2VxIGRhdGEgLSB3aXRoIHRoZSBkaWZmZXJlbmNlIGJlaW5nIHdoZXRoZXIgb25lIHBlcmZvcm1zIGFuIGFsaWdubWVudCB0byB0aGUgcmVmZXJlbmNlIGdlbm9tZSBvciBub3QuCgpSZWNlbnQgdG9vbHMgZm9yIFJOQS1zZXEgYW5hbHlzaXMgKGUuZy4gYHNhbG1vbmAsIGBrYWxsaXN0b2ApIGRvIG5vdCByZXF1aXJlIHRoZSB0aW1lLWNvbnN1bWluZyBzdGVwIG9mIHdob2xlLWdlbm9tZSBhbGlnbm1lbnQgdG8gYmUgcGVyZm9ybWVkLCBhbmQgY2FuIHRoZXJlZm9yZSBwcm9kdWNlIGdlbmUtbGV2ZWwgY291bnRzIGluIGEgbXVjaCBmYXN0ZXIgdGltZSBmcmFtZS4gVGhleSBub3QgcmVxdWlyZSB0aGUgY3JlYXRpb24gb2YgbGFyZ2UgYmFtIGZpbGVzLCB3aGljaCBpcyB1c2VmdWwgaWYgY29uc3RyYWluZWQgYnkgZmlsZSBzcGFjZSBvbiBHYWxheHkuCgohW10oaHR0cHM6Ly9oYmN0cmFpbmluZy5naXRodWIuaW8vSW50cm8tdG8tcm5hc2VxLWhwYy1ndC9pbWcvYWxpZ25tZW50ZnJlZV93b3JrZmxvd19hdWcyMDE3LnBuZykKCihpbWFnZSBmcm9tIEhhcnZhcmQgQmlvaW5mb3JtYXRpY3MgQ29yZSkKCgotLS0tLQoKIyMgQmFja2dyb3VuZAoKIyMjIyBXaGVyZSBkbyB0aGUgZGF0YSBpbiB0aGlzIHR1dG9yaWFsIGNvbWUgZnJvbT8KVGhlIGRhdGEgZm9yIHRoaXMgdHV0b3JpYWwgY29tZXMgZnJvbSBhIEpvdXJuYWwgb2YgRXhwZXJpbWVudGFsIE1lZGljaW5lIHBhcGVyIFsiSXRyYWNvbmF6b2xlIHRhcmdldHMgY2VsbCBjeWNsZSBoZXRlcm9nZW5laXR5IGluIGNvbG9yZWN0YWwgY2FuY2VyIl0oaHR0cHM6Ly9wdWJtZWQubmNiaS5ubG0ubmloLmdvdi8yOTg1MzYwNy8pLiBUaGlzIHN0dWR5IGV4YW1pbmVzIHRoZSBleHByZXNzaW9uIHByb2ZpbGVzIG9mIHR3byBjZWxsIGxpbmVzIGluIHJlc3BvbnNlIHRvIHRyZWF0bWVudCB3aXRoIGl0cmFjb25hem9sZS4KCgoKRm9yIHRoaXMgdHV0b3JpYWwsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlICp3ZXQtbGFiKiBzdGFnZXMgb2YgdGhlIGV4cGVyaW1lbnQgaGF2ZSBiZWVuIHBlcmZvcm1lZCBhbmQgd2UgYXJlIG5vdyBpbiB0aGUgcmlnaHQtaGFuZCBicmFuY2ggb2YgdGhlIHdvcmtmbG93LiBJbiB0aGlzIHR1dG9yaWFsIHdlIHdpbGwgZGVtb25zdHJhdGUgdGhlIHN0ZXBzIG9mICoqUXVhbGl0eSBhc3Nlc3NtZW50KiosICoqYWxpZ25tZW50KiosICoqcXVhbnRpZmljYXRpb24qKiBhbmQgKipkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiB0ZXN0aW5nKiouCgpUaGUgZmFzdHEgZGF0YSBmb3IgdGhpcyBleHBlcmltZW50IHdlcmUgbWFkZSBhdmFpbGFibGUgb24gdGhlIFNlcXVlbmNpbmcgUmVhZCBBcmNoaXZlIChTUkEpIHdpdGggYWNjZXNzaW9uIFNSUDE0NDQ5Ni4gKipGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgd29ya3Nob3Agd2UgaGF2ZSBjcmVhdGVkIGEgZG93bnNhbXBsZWQgZGF0YXNldCoqCgpUaGUgZXhwZXJpbWVudGFsIGRlc2lnbiBmb3IgdGhlIGRhdGFzZXQgaXMgc3VtbWFyaXNlZCBpbiB0aGUgdGFibGUgYmVsb3cuCgpydW4JfCBuYW1lCXwgY2VsbF9saW5lCXwgY29uZGl0aW9uCi0tLS18LS0tLS0tLXwtLS0tLS0tLS0tLXwtLS0tLS0tLS0gClNSUjcxMDgzODgJfCBIVDU1X0NPTlRfMQl8IEhUNTUJfCBETVNPClNSUjcxMDgzODkJfCBIVDU1X0NPTlRfMgl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTAJfCBIVDU1X0NPTlRfMwl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTEJfCBIVDU1X0NPTlRfNAl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTIJfCBIVDU1X0lUUkFfMQl8IEhUNTUJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODM5Mwl8IEhUNTVfSVRSQV8yCXwgSFQ1NQl8IElUUkFDT05BWk9MRQpTUlI3MTA4Mzk0CXwgSFQ1NV9JVFJBXzMJfCBIVDU1CXwgSVRSQUNPTkFaT0xFClNSUjcxMDgzOTUJfCBIVDU1X0lUUkFfNAl8IEhUNTUJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODM5Ngl8IFNXOTQ4X0NPTlRfMSB8IFNXOTQ4CXwgRE1TTwpTUlI3MTA4Mzk3CXwgU1c5NDhfQ09OVF8yIHwgU1c5NDgJfCBETVNPClNSUjcxMDgzOTgJfCBTVzk0OF9DT05UXzMgfCBTVzk0OAl8IERNU08KU1JSNzEwODM5OQl8IFNXOTQ4X0NPTlRfNCB8IFNXOTQ4CXwgRE1TTwpTUlI3MTA4NDAwCXwgU1c5NDhfSVRSQV8xIHwgU1c5NDgJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODQwMQl8IFNXOTQ4X0lUUkFfMiB8IFNXOTQ4CXwgSVRSQUNPTkFaT0xFClNSUjcxMDg0MDIJfCBTVzk0OF9JVFJBXzMgfCBTVzk0OAl8IElUUkFDT05BWk9MRQpTUlI3MTA4NDAzCXwgU1c5NDhfSVRSQV80IHwgU1c5NDgJfCBJVFJBQ09OQVpPTEUKCiMjIyMgRGlncmVzc2lvbjogSG93IHRvIGRvd25sb2FkIHJhdyBzZXF1ZW5jaW5nIGZpbGVzCgpUaGUgU2VxdWVuY2luZyBSZWFkIEFyY2hpdmUgKFNSQSkgaXMgY29tbW9ubHktdXNlZCB0byBzdG9yZSB0aGUgcmF3IGRhdGEgZnJvbSBzZXF1ZW5jaW5nIGV4cGVyaWVtZW50cyBhbmQgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIE5DQkkgd2Vic2l0ZS4gSG93ZXZlciwgdGhlIGludGVyZmFjZSBpcyBub3QgcGFydGljdWxhcmx5IGZyaWVuZGx5IGFuZCB0aGUgbGlua3MgdG8gZG93bmxvYWQgZGF0YSBhbmQgbm90IGVhc3kgdG8gb2J0YWluLgoKQW4gZWFzaWVyIGFsdGVybmF0aXZlIGV4aXN0cyBpbiB0aGUgZm9ybSBvZiBTUkEgRXhwbG9yZXIKCi0gW2h0dHBzOi8vc3JhLWV4cGxvcmVyLmluZm8vXShodHRwczovL3NyYS1leHBsb3Jlci5pbmZvLykKCjxpbWcgc3JjPSJtZWRpYS9zcmFfZXhwbG9yZXIucG5nIi8+CgpUaGUgU1JBIGFjY2Vzc2lvbiAodXN1YWxseSBmb3VuZCBpbiBhIHBhcGVyIGRlc2NyaWJpbmcgdGhlIGRhdGFzZXQpIGNhbiBiZSBlbnRlcmVkIGludG8gdGhlIFNlYXJjaCBib3gsIGFuZCBhbGwgdGhlIHNhbXBsZXMgYmVsb25naW5nIHRvIHRoYXQgZGF0YXNldCBzaG91bGQgYmUgZm91bmQuIFNhbXBsZXMgb2YgaW50ZXJlc3QgY2FuIGJlIHNhdmVkLCBhbmQgdXBvbiAiY2hlY2tvdXQiIHRoZSBkb3dubG9hZCBsaW5rcyAoVVJMcykgd2lsbCBiZSBkaXNwbGF5ZWQuIEEgY29tbWFuZC1saW5lIHRvb2wgc3VjaCBhcyBgY3VybGAgb3IgYHdnZXRgIGNhbiB0aGVuIGJlIHVzZWQgdG8gZG93bmxvYWQgdGhlIGZpbGVzIGxvY2FsbHkuCgojIyBTZWN0aW9uIDE6IFByZXBhcmF0aW9uCiMjIyMgMS4gU2lnbi11cCB0byB0aGUgRXVyb3BlYW4gR2FsYXh5IHNlcnZlcgoKCi0gaHR0cHM6Ly91c2VnYWxheHkuZXUKLSBUaGUgQXVzdHJhbGlhbiBzZXJ2ZXIgaXMgYW4gYWx0ZXJuYXRpdmUgaWYgdGhlIEV1cm9wZWFuIG9uZSBpcyBkb3duOi0gaHR0cHM6Ly91c2VnYWxheHkub3JnLmF1LwoKCioqTWFrZSBzdXJlIHlvdSBjaGVjayB5b3VyIGVtYWlsIHRvIGFjdGl2YXRlIHlvdXIgYWNjb3VudCoqCgpOb3csIHVzZSB0aGlzIGxpbmsgdG8gYWNjZXNzIGEgc3BlY2lhbCBxdWV1ZS4gVGhpcyBsaW5rIHdpbGwgb25seSBiZSBhY3RpdmUgb24gKipEZWNlbWJlciA2dGgqKi4KCi0gW2h0dHBzOi8vdXNlZ2FsYXh5LmV1L2pvaW4tdHJhaW5pbmcvc2JjZ2FsYXh5LTIwMjEtMTItMDFdKGh0dHBzOi8vdXNlZ2FsYXh5LmV1L2pvaW4tdHJhaW5pbmcvc2JjZ2FsYXh5LTIwMjEtMTItMDEpCgojIyMjIDIuIERvd25sb2FkIHRoZSBjb3Vyc2UgZGF0YQoKVGhlIGRhdGEgZm9yIHRoaXMgY291cnNlIGhhdmUgYWxsIGJlZW4gc2hhcmVkIG9uIGEgZ29vZ2xlIGRyaXZlLiBJZiB5b3UgaGF2ZSBub3QgZG9uZSBzbyBhbHJlYWR5LCBwbGVhc2UgZ28gdG8gdGhpcyBkaXJlY3RvcnkgYW5kIGRvd25sb2FkIHRoZSBmb2xsb3dpbmcgZmlsZXMKCmh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9kcml2ZS9mb2xkZXJzLzFSU3V2bDlzaEF3MTJCajc3dVlTVWRXdGtaNVNUNUVXaT91c3A9c2hhcmluZwoKLSBgU1JSNzEwODM4OC5mYXN0cS5nemAKLSBgU1JSNzEwODM4OS5mYXN0cS5nemAKLSBgU1JSNzEwODM5Mi5mYXN0cS5nemAKLSBgU1JSNzEwODM5My5mYXN0cS5nemAKLSBgSG9tb19zYXBpZW5zLkdSQ2gzOC5jZG5hLmFsbC5mYS5nemAKLSBgSG9tb19zYXBpZW5zLkdSQ2gzOC4xMDQuZ3RmLmd6YAotIGB0eDJnZW5lLnR4dGAKCgojIyMjIDMuICBJbXBvcnQgdGhlIFJOQS1zZXEgZGF0YSBmb3IgdGhlIHdvcmtzaG9wLgoKV2UgY2FuIGdvaW5nIHRvIGltcG9ydCB0aGUgWypmYXN0cSogZmlsZXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZBU1RRX2Zvcm1hdCkgZm9yIHRoaXMgZXhwZXJpbWVudC4gVGhpcyBpcyBhIHN0YW5kYXJkIGZvcm1hdCBmb3Igc3RvcmluZyByYXcgc2VxdWVuY2luZyByZWFkcyBhbmQgdGhlaXIgYXNzb2NpYXRlZCBxdWFsaXR5IHNjb3Jlcy4gVG8gbWFrZSB0aGUgcHJhY3RpY2FsIHF1aWNrZXIsIHdlIGhhdmUgKmRvd25zYW1wbGVkKiB0aGUgb3JpZ2luYWwgZmFzdHEgZmlsZXMgdG8gYSBxdWFydGVyIG9mIGEgbWlsbGlvbiByZWFkcy4KCgoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoKIyMjIyAqKkdldCBEYXRhIC0+IFVwbG9hZCBGaWxlICoqIAoKPC9kaXY+CgpZb3UgY2FuIGltcG9ydCB0aGUgZGF0YSBieToKCjEuICBJbiB0aGUgdG9vbCBwYW5lbCBsb2NhdGVkIG9uIHRoZSBsZWZ0LCB1bmRlciBCYXNpYyBUb29scyBzZWxlY3QgKipHZXQgRGF0YSA+IFVwbG9hZCBGaWxlKiouIENsaWNrIG9uIHRoZSAqKkNob29zZSBsb2NhbCBmaWxlKiogYnV0dG9uIG9uIHRoZQogICAgYm90dG9tIHNlY3Rpb24gb2YgdGhlIHBvcC11cCB3aW5kb3cuCjIuICBOYXZpZ2F0ZSB0byB0aGUgYGZhc3RxYCBkaXJlY3Rvcnkgb2YgdGhlIHppcCBmaWxlIHRoYXQgeW91IGRvd25sb2FkZWQgZnJvbSBnb29nbGUgZHJpdmUgYW5kIHNlbGVjdCB0aGVzZSB0d28gZmlsZXMgZnJvbSB0aGUgSFQ1NS1ETVNPIGNvbmRpdGlvbi4gCgpgU1JSNzEwODM4OC5mYXN0cS5nemAKYFNSUjcxMDgzODkuZmFzdHEuZ3pgCiAKIGFuZCB0aGVzZSB0d28gZmlsZXMgYXJlIGZyb20gdGhlIEhUNTUgSVRSQUNPTkFaT0xFIGNvbmRpdGlvbi4KCmBTUlI3MTA4MzkyLmZhc3RxLmd6YApgU1JSNzEwODM5My5mYXN0cS5nemAKCmFsc28gdXBsb2FkIHRoZSBmaWxlcyBgSG9tb19zYXBpZW5zLkdSQ2gzOC5jZG5hLmFsbC5mYS5nemAsIGBIb21vX3NhcGllbnMuR1JDaDM4LjEwNC5ndGYuZ3pgIGFuZCBgdHgyZ2VuZS50eHRgLiBUaGVzZSBhcmUgcmVmZXJlbmNlIGZpbGVzIHRoYXQgd2Ugd2lsbCB1c2UgbGF0ZXIuCgozLiAgWW91IHNob3VsZCBub3cgaGF2ZSB0aGVzZSA0IGZhc3RxIGZpbGVzIGluIHlvdXIgaGlzdG9yeToKICAgIC0gYFNSUjcxMDgzODguZmFzdHEuZ3pgCiAgICAtIGBTUlI3MTA4Mzg5LmZhc3RxLmd6YAogICAgLSBgU1JSNzEwODM5Mi5mYXN0cS5nemAKICAgIC0gYFNSUjcxMDgzOTMuZmFzdHEuZ3pgCgpUaGUgYW5ub3RhdGlvbiBmaWxlcyBtYXkgdGFrZSBhIHdoaWxlIGxvbmdlciB0byB1cGxvYWQKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KVGhlIGAuZ3pgIGF0IHRoZSBlbmQgb2YgZWFjaCBmaWxlIG5hbWUgbWVhbnMgdGhhdCBpdCBpcyAqY29tcHJlc3NlZCogKGxpa2UgYSB6aXAgZmlsZSkuIAo8L2Rpdj4KCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KWW91IGNhbiB1cGxvYWQgdGhlIG90aGVyIGZpbGVzIGZvciBleHRyYSBwcmFjdGljZSBpZiB5b3Ugd2lzaAo8L2Rpdj4KCiMjIyBRdWFsaXR5IGFzc2Vzc21lbnQgd2l0aCBGYXN0UUMgKE9wdGlvbmFsKQoKW0Zhc3RRQ10oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjLykgaXMgYSBwb3B1bGFyIHRvb2wgZnJvbSBbQmFicmFoYW0gSW5zdGl0dXRlIEJpb2luZm9ybWF0aWNzIEdyb3VwXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9pbmRleC5odG1sKSB1c2VkIGZvciAqcXVhbGl0eSBhc3Nlc3NtZW50KiBvZiBzZXF1ZW5jaW5nIGRhdGEuIE1vc3QgQmlvaW5mb3JtYXRpY3MgcGlwZWxpbmVzIHdpbGwgdXNlIEZhc3RRQywgb3Igc2ltaWxhciB0b29scyBpbiB0aGUgZmlyc3Qgc3RhZ2Ugb2YgdGhlIGFuYWx5c2lzLiBUaGUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy9IZWxwLykgZm9yIEZhc3RRQyB3aWxsIGhlbHAgeW91IHRvIGludGVycHJldCB0aGUgcGxvdHMgYW5kIHN0YXRzIHByb2R1Y2VkIGJ5IHRoZSB0b29sLiBBIHRyYWZmaWMgbGlnaHQgc3lzdGVtIGlzIHVzZWQgdG8gYWxlcnQgdGhlIHVzZXIncyBhdHRlbnRpb24gdG8gcG9zc2libGUgaXNzdWVzLiBIb3dldmVyLCBpdCBpcyB3b3J0aCBiZWFyaW5nIGluIG1pbmQgdGhhdCB0aGUgdG9vbCBpcyBibGluZCB0byB0aGUgcGFydGljdWxhciB0eXBlIG9mIHNlcXVlbmNpbmcgeW91IGFyZSBwZXJmb3JtaW5nIChpLmUuIHdob2xlLWdlbm9tZSwgQ2hJUC1zZXEsIFJOQS1zZXEpLCBzbyBzb21lIHdhcm5pbmdzIG1pZ2h0IGJlIGV4cGVjdGVkIGR1ZSB0byB0aGUgbmF0dXJlIG9mIHlvdXIgZXhwZXJpbWVudC4KCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KCiMjIyMgKkZhc3RRIFF1YWxpdHkgQ29udHJvbCogLT4gKkZhc3RRQyBSZWFkIFF1YWxpdHkgcmVwb3J0cyoKCjwvZGl2PgoKLSBTZWxlY3Qgb25lIG9mIHRoZSBGQVNUUSBmaWxlcyBhcyBpbnB1dCBhbmQgKkV4ZWN1dGUqIHRoZSB0b29sLgotIFdoZW4gdGhlIHRvb2wgZmluaXNoZXMgcnVubmluZywgeW91IHNob3VsZCBoYXZlIGFuIEhUTUwgZmlsZSBpbiB5b3VyIEhpc3RvcnkuIENsaWNrIG9uIHRoZSBleWUgaWNvbiB0byB2aWV3IHRoZSB2YXJpb3VzIHF1YWxpdHkgbWV0cmljcy4KLSBSdW4gRmFzdHFjIG9uIHRoZSByZW1haW5nIGZhc3RxIGZpbGVzLCBidXQgZG9uJ3QgZXhhbWluZSB0aGUgcmVzdWx0cyBqdXN0IHlldC4KCgo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+CgoqKlF1ZXN0aW9uOiBEbyB0aGUgZGF0YSBzZWVtIHRvIGJlIG9mIHJlYXNvbmFibGUgcXVhbGl0eT8gKioKCllvdSBjYW4gdXNlIHRoZSBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjL0hlbHAvMyUyMEFuYWx5c2lzJTIwTW9kdWxlcy8pIHRvIGhlbHAgaW50ZXJwcmV0IHRoZSBwbG90cwoKPC9kaXY+CgpJZiBwb29yIHF1YWxpdHkgcmVhZHMgdG93YXJkcyB0aGUgZW5kcyBvZiByZWFkcyBhcmUgY29uc2lkZXJlZCB0byBiZSBhIHByb2JsZW0sIG9yIHRoZXJlIGlzIGNvbnNpZGVyYWJsZSBhZGFwdGVyIGNvbnRhbWluYXRpb24sIHdlIGNhbiBlbXBsb3kgdmFyaW91cyB0b29scyB0byAqdHJpbSogb3VyIGRhdGEuCgpIb3dldmVyLCBhIHJlY2VudCBwYXBlciBkZW1vbnN0cmF0ZWQgdGhhdCByZWFkIHRyaW1taW5nIGlzIG5vIGxvbmdlciByZXF1aXJlZCBwcmlvciB0byBhbGlnbm1lbnQ6LSBodHRwczovL3d3dy5iaW9yeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvODMzOTYydjEKCgo8ZGl2IGNsYXNzPSJ3YXJuaW5nIj4KCklmIHlvdSBhbHNvIHN1c3BlY3QgY29udGFtaW5hdGlvbiBieSBhbm90aGVyIG9yZ2FuaXNtLCBvciByUk5BIHByZXNlbnQgaW4geW91ciBkYXRhLCB5b3UgY2FuIHVzZSB0aGUgc29ydE1lUk5BIHRvb2wgdG8gcmVtb3ZlIHRoaXMgYXJ0ZWZhY3QuCjwvZGl2PgoKCiMjIyBDb21iaW5pbmcgUUMgcmVwb3J0cwoKSXQgY2FuIGJlIHF1aXRlIHRpcmVzb21lIHRvIGNsaWNrIHRocm91Z2ggbXVsdGlwbGUgUUMgcmVwb3J0cyBhbmQgY29tcGFyZSB0aGUgcmVzdWx0cyBmb3IgZGlmZmVyZW50IHNhbXBsZXMuIEl0IGlzIHVzZWZ1bCB0byBoYXZlIGFsbCB0aGUgUUMgcGxvdHMgb24gdGhlIHNhbWUgcGFnZSBzbyB0aGF0IHdlIGNhbiBtb3JlIGVhc2lseSBzcG90IHRyZW5kcyBpbiB0aGUgZGF0YS4KClRoZSBbbXVsdGlxY10oaHR0cHM6Ly9tdWx0aXFjLmluZm8vKSB0b29sIGhhcyBiZWVuIGRlc2lnbmVkIGZvciB0aGUgdGFza3Mgb2YgYWdncmVnYXRpbmcgcWMgcmVwb3J0cyBhbmQgY29tYmluaW5nIGludG8gYSBzaW5nbGUgcmVwb3J0IHRoYXQgaXMgZWFzeSB0byBkaWdlc3QuCgoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoKKkZBU1RRIFF1YWxpdHkgQ29udHJvbCogLT4gKk11bHRpcWMqCgo8L2Rpdj4KClVuZGVyICpXaGljaCB0b29sIHdhcyB1c2VkIGdlbmVyYXRlIGxvZ3M/KiBDaG9vc2UgKmZhc3RxYyogYW5kIHNlbGVjdCB0aGUgUmF3RGF0YSBvdXRwdXQgZnJvbSB0aGUgZmFzdHFjIHJ1biBvbiBlYWNoIG9mIHlvdXIgYmFtIGZpbGVzLgoKCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4KClF1ZXN0aW9uOiBSZXBlYXQgdGhlIEZhc3RRQyBhbmFseXNpcyBmb3IgdGhlIHJlbWFpbmluZyBmYXN0cSBmaWxlcyBhbmQgY29tYmluZSB0aGUgcmVwb3J0cyB3aXRoIGBtdWx0aVFDYC4gRG8gdGhlIGZhc3RxIGZpbGVzIHNlZW0gdG8gaGF2ZSBjb25zaXN0ZW50bHkgaGlnaC1xdWFsaXR5Pwo8L2Rpdj4KCgojIyBTZWN0aW9uIDI6IFF1YW50aWZpY2F0aW9uCgpXZSBjYW4gYWxpZ24gb3VyIFJOQS1zZXEgcmVhZHMgdG8gYSByZWZlcmVuY2UgKmdlbm9tZSosIGFuZCB0aGVuIG92ZXJsYXAgd2l0aCBrbm93IGdlbmUgY29vcmRpbmF0ZXMsIGJ1dCBtYW55IHByZWZlciB0byBhbGlnbiBkaXJlY3RseSB0byB0aGUgKnRyYW5zY3JpcHRvbWUqIHNlcXVlbmNlcyB1c2luZyBhIG1ldGhvZCBzdWNoIGFzIHNhbG1vbiBvciBrYWxsaXN0by4gV2Ugd2lsbCBkZW1vbnN0cmF0ZSB0aGUgc2FsbW9uIHByb3RvY29sLgoKIyMjIE9idGFpbmluZyB0aGUgZmlsZXMgZm9yIHNhbG1vbgoKMSkgY0ROQSBmYXN0YSBmaWxlCgpUaGlzIGZpbGUgaGFzIGJlZW4gcHJvdmlkZWQgaW4gdGhlIGdvb2dsZSBkcml2ZSBmb2xkZXIgYW5kIHNob3VsZCBoYXZlIGJlZW4gdXBsb2FkZWQgdG8geW91ciBHYWxheHkgaGlzdG9yeS4KCi0gW2h0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9kcml2ZS9mb2xkZXJzLzFSU3V2bDlzaEF3MTJCajc3dVlTVWRXdGtaNVNUNUVXaT91c3A9c2hhcmluZ10oaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMVJTdXZsOXNoQXcxMkJqNzd1WVNVZFd0a1o1U1Q1RVdpP3VzcD1zaGFyaW5nKQoKSG93ZXZlciwgaXQgaXMgdXNlZnVsIHRvIGtub3cgd2hlcmUgdGhpcyBmaWxlIGNhbWUgZnJvbSBpbiBjYXNlIHlvdSBhcmUgbm90IHdvcmtpbmcgd2l0aCBIdW1hbiBkYXRhLiBUaGUgZmlsZSB3YXMgb2J0YWluZWQgZnJvbSBbRW5zZW1ibF0oaHR0cDovL20uZW5zZW1ibC5vcmcvaW5mby9kYXRhL2Z0cC9pbmRleC5odG1sKSBieSBjbGlja2luZyBvbiB0aGUgKipjRE5BIChGQVNUQSkqKiBsaW5rIGZvciB0aGUgYXBwcm9wcmlhdGUgb3JnYW5pc20gKEh1bWFuKS4gCgo8aW1nIHNyYz0ibWVkaWEvZW5zZW1ibF9kb3dubG9hZC5wbmciLz4KCk9uIHRoZSBuZXh0IHNjcmVlbiwgIFJpZ2h0LWNsaWNrIHRvIHNhdmUgdGhlIGAuY2RuYS5hbGwuZmEuZ3pgIHRvIHlvdXIgY29tcHV0ZXIKCjxpbWcgc3JjPSJtZWRpYS9jZG5hX2Rvd25sb2FkLnBuZyIvPgoKMikgVHJhbnNjcmlwdCBtYXBwaW5nIGZpbGUKCkJ5IGRlZmF1bHQsIHNhbG1vbiB3aWxsIHByb2R1Y2UgY291bnRzIGZvciBlYWNoICp0cmFuc2NyaXB0Ki4gVGhpcyBtaWdodCBiZSB3aGF0IHdlIHdhbnQsIGJ1dCBmb3IgbW9zdCBzdGFuZGFyZCBhbmFseXNlcyBpdCBpcyBwcmVmZXJhYmxlIHRvIHdvcmsgYXQgdGhlIGdlbmUtbGV2ZWwuIFdlIHRoZXJlZm9yZSBoYXZlIHRvIHRlbGwgc2FsbW9uIGhvdyB0aGUgdHJhbnNjcmlwdHMgaW4gdGhlIGNETkEgZmlsZSByZWxhdGUgdG8ga25vd24gZ2VuZXMuIFN1Y2ggYSBmaWxlIGNhbiBiZSBvYnRhaW5lZCBmcm9tIFtiaW9tYXJ0XShodHRwczovL2Vuc2VtYmwub3JnL2Jpb21hcnQvbWFydHZpZXcvKS4gCgotIFNlbGVjdCB0aGUgRW5zZW1ibCBnZW5lcyAoMTA0KSBkYXRhYmFzZQotIFNlbGVjdCB0aGUgZGF0YXNldCBIdW1hbiBnZW5lcyAoR1JDaDM4LjEzKQotIEluIEF0dHJpYnV0ZXMsIGNsaWNrIHRoZSAiKyIgYnV0dG9uIG5leHQgdG8gR0VORSBhbmQgc2VsZWN0ICpUcmFuc2NyaXB0IHN0YWJsZSBJRCB2ZXJzaW9uKiBhbmQgKkdlbmUgc3RhYmxlIElEKi4gTWFrZSBzdXJlIHRoZSBvcmRlciBvbiB0aGUgbGVmdC1oYW5kIHBhbmVsIGlzICpUcmFuc2NyaXB0IHN0YWJsZSBJRCB2ZXJzaW9uKiwgZm9sbG93ZWQgYnkgKkdlbmUgc3RhYmxlIElEKi4gVGhpcyB3aWxsIGFmZmVjdCB0aGUgY29sdW1uIG9yZGVyIGluIHRoZSBmaWxlLiBZb3UgY2FuIHRpY2sgLyB1bnRpY2sgdGhlIElEcyB0byBtYWtlIHN1cmUgdGhlIG9yZGVyIGlzIGNvcnJlY3QuCgo8aW1nIHNyYz0ibWVkaWEvYmlvbWFydF90cmFuc2NyaXB0X2V4cG9ydC5QTkciLz4KCi0gQ2xpY2sgdGhlIFJlc3VsdHMgYnV0dG9uIGluIHRoZSB0b3AgbGVmdCBjb3JuZXIgdG8gc2VlIGEgcHJldmlldyBvZiB0aGUgcmVzdWx0cy4gQ2xpY2tpbmcgdGhlIEdvIGJ1dHRvbiB3aWxsIGV4cG9ydCB0aGUgcmVzdWx0cyB0byBhIGZpbGUKCjxpbWcgc3JjPSJtZWRpYS9iaW9tYXJ0X3RyYW5zY3JpcHRfcHJldmlldy5QTkciLz4KCgoqKkl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSBmaWxlIGRvd25sb2FkZWQgZnJvbSBCaW9tYXJ0IGlzIGVkaXRlZCBzbyB0aGF0IHRoZSBjb2x1bW4gaGVhZGluZ3MgZG8gbm90IGNvbnRhaW4gYW55IHNwYWNlcyoqLiBZb3UgY2FuIGRvIHRoaXMgaW4gYSB0ZXh0IGVkaXRvci4gVGhlIGVkaXRlZCBmaWxlIHNob3VsZCBsb29rIGxpa2UgdGhpcy4KCjxpbWcgc3JjPSJtZWRpYS9iaW9tYXJ0X3RyYW5zY3JpcHRfZWRpdC5QTkciLz4KCjxkaXYgY2xhc3M9Indhcm5pbmciPgoKSXQgaXMgaW1wb3J0YW50IHRvIG1ha2Ugc3VyZSB0aGUgdmVyc2lvbiBudW1iZXIgb2YgeW91ciB0cmFuc2NyaXB0IGZpbGUgYW5kIHRoZSBiaW9tYVJ0IGRhdGFzZXQgYXJlICoqdGhlIHNhbWUqKiwgb3RoZXJ3aXNlIHNvbWUgb2YgdGhlIHN0ZXBzIGRvd25zdHJlYW0gbWlnaHQgbm90IHdvcmsgYXMgZXhwZWN0ZWQuCjwvZGl2PgoKSWYgeW91IGhhdmUgcHJvYmxlbXMsIHRoaXMgbWFwcGluZyBmaWxlIGlzIGFsc28gcHJvdmlkZWQgaW4gdGhlIGdvb2dsZSBkcml2ZSBhcyBgdHgyZ2VuZS50eHRgLgoKMykgQW5ub3RhdGlvbiBmaWxlIChvcHRpb25hbCkKClRoZSBFbnNlbWJsIGdlbmUgSURzIGFyZSBub3QgcGFydGljdWxhcmx5IG1lbW9yYWJsZSwgc28gaXQgd291bGQgYmUgaGlnaGx5IGJlbmVmaWNpYWwgdG8gaGF2ZSBvdGhlciBhbm5vdGF0aW9ucyBhdCBoYW5kIHRvIGhlbHAgdXMgaW50ZXJwcmV0IHRoZSBkYXRhIGRvd25zdHJlYW0uIFdlIGNhbiB1c2UgdGhlIGJpb21hcnQgd2Vic2l0ZSBhZ2FpbiB0byBwcm9kdWNlIGEgdGFibGUgdG8gZG93bnN0cmVhbSBpbnRyZXByZXRhdGlvbi4gCgpUaGlzIHRpbWUsIHNlbGVjdCBvbmx5IHRoZSAqR2VuZSBTdGFibGUgSUQqIHRpY2tib3ggaW4gdGhlIEdFTkUgYm94LiBFeHBhbmQgdGhlIEVYVEVSTkFMIHBhbmVsIGJ5IGNsaWNraW5nIHRoZSAiKyIgbmV4dCB0byBFWFRFUk5BTCwgYW5kIHNlbGVjdCAqSEdOQyBzeW1ib2wqIGFuZCAqTkNCSSBnZW5lIChmb3JtZXJseSBFbnRyZXpnZW5lKSBJRCoKCgojIyMgc2FsbW9uIGNvbmZpZ3VyYXRpb24gYW5kIHJ1bm5pbmcKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKipSTkEgQW5hbHlzaXMqKiAtPiAqKlNhbG1vbiBxdWFudCoqCjwvZGl2PgoKCi0gU2VsZWN0IHRoZSAqSG9tb19zYXBpZW5zX0dSQ2gzOC5jZG5hLmFsbC5mYS5neiogZmlsZSBhcyB0aGUgVHJhbnNjcmlwdHMgZmFzdGEgZmlsZQotIFNlbGVjdCBhbGwgeW91ciB1cGxvYWRlZCBmYXN0cSBmaWxlcyBhcyB5b3VyIERhdGEgSW5wdXQgRkFTVFEvRkFTVEEgZmlsZQotIFNjcm9sbCBkb3duIHRvICpGaWxlIGNvbnRhaW5pbmcgYSBtYXBwaW5nIG9mIHRyYW5zY3JpcHRzIHRvIGdlbmVzKiBhbmQgc2VsZWN0IHRoZSBgdHgyZ2VuZS50eHRgIGZpbGUKClR3byBqb2JzIHdpbGwgbm93IGJlIHF1ZXVlZCBmb3IgZWFjaCBzYW1wbGUgZmFzdHEgZmlsZS4gVGhlIFF1YW50aWZpY2F0aW9uIG91dHB1dCB3aWxsIGNvbnRhaW4gdHJhbnNjcmlwdC1sZXZlbCBkYXRhLCBhbmQgdGhlIEdlbmUgUXVhbnRpZmljYXRpb24gb3V0cHV0IHdpbGwgYmUgYXQgdGhlICpnZW5lLWxldmVsKi4gV2Ugc2hvdWxkIGV4cGVjdCB0aGUgbnVtYmVyIG9mIGxpbmVzIGluIHRoZSBHZW5lIFF1YW50aWZpY2F0aW9uIGZpbGUgdG8gYmUgc3Vic3RhbnRpYWxseSBsZXNzLiBJZiBub3QsIHlvdSB3aWxsIG5lZWQgdG8gY2hlY2sgdGhhdCB5b3VyIHRyYW5zY3JpcHQgbWFwcGluZyBmaWxlIHdhcyBjb3JyZWN0LgoKVGhlIEdlbmUgUXVhbnRpZmljYXRpb24gb3V0cHV0IGZyb20gZWFjaCBzYW1wbGUgY29tcHJpc2VzIHRoZSBmb2xsb3dpbmcgY29sdW1ucyAodGFrZW4gZnJvbSB0aGUgW3NhbG1vbiBkb2N1bWVudGF0aW9uXShodHRwczovL3NhbG1vbi5yZWFkdGhlZG9jcy5pby9lbi9sYXRlc3QvZmlsZV9mb3JtYXRzLmh0bWwpKQoKLSBOYW1lIOKAlCBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgdHJhbnNjcmlwdCBwcm92aWRlZCBpbiB0aGUgaW5wdXQgdHJhbnNjcmlwdCBkYXRhYmFzZSAoRkFTVEEgZmlsZSkuCi0gTGVuZ3RoIOKAlCBUaGlzIGlzIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCB0cmFuc2NyaXB0IGluIG51Y2xlb3RpZGVzLgotIEVmZmVjdGl2ZUxlbmd0aCDigJQgVGhpcyBpcyB0aGUgY29tcHV0ZWQgZWZmZWN0aXZlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHRyYW5zY3JpcHQuIEl0IHRha2VzIGludG8gYWNjb3VudCBhbGwgZmFjdG9ycyBiZWluZyBtb2RlbGVkIHRoYXQgd2lsbCBlZmZlY3QgdGhlIHByb2JhYmlsaXR5IG9mIHNhbXBsaW5nIGZyYWdtZW50cyBmcm9tIHRoaXMgdHJhbnNjcmlwdCwgaW5jbHVkaW5nIHRoZSBmcmFnbWVudCBsZW5ndGggZGlzdHJpYnV0aW9uIGFuZCBzZXF1ZW5jZS1zcGVjaWZpYyBhbmQgZ2MtZnJhZ21lbnQgYmlhcyAoaWYgdGhleSBhcmUgYmVpbmcgbW9kZWxlZCkuCi0gVFBNIOKAlCBUaGlzIGlzIHNhbG1vbuKAmXMgZXN0aW1hdGUgb2YgdGhlIHJlbGF0aXZlIGFidW5kYW5jZSBvZiB0aGlzIHRyYW5zY3JpcHQgaW4gdW5pdHMgb2YgVHJhbnNjcmlwdHMgUGVyIE1pbGxpb24gKFRQTSkuIFRQTSBpcyB0aGUgcmVjb21tZW5kZWQgcmVsYXRpdmUgYWJ1bmRhbmNlIG1lYXN1cmUgdG8gdXNlIGZvciBkb3duc3RyZWFtIGFuYWx5c2lzLgotIE51bVJlYWRzIOKAlCBUaGlzIGlzIHNhbG1vbuKAmXMgZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiByZWFkcyBtYXBwaW5nIHRvIGVhY2ggdHJhbnNjcmlwdCB0aGF0IHdhcyBxdWFudGlmaWVkLiBJdCBpcyBhbiDigJxlc3RpbWF0ZeKAnSBpbnNvZmFyIGFzIGl0IGlzIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgcmVhZHMgdGhhdCBoYXZlIG9yaWdpbmF0ZWQgZnJvbSBlYWNoIHRyYW5zY3JpcHQgZ2l2ZW4gdGhlIHN0cnVjdHVyZSBvZiB0aGUgdW5pcXVlbHkgbWFwcGluZyBhbmQgbXVsdGktbWFwcGluZyByZWFkcyBhbmQgdGhlIHJlbGF0aXZlIGFidW5kYW5jZSBlc3RpbWF0ZXMgZm9yIGVhY2ggdHJhbnNjcmlwdC4KCk5vdGUgdGhhdCB3ZSBhcmUgdXNpbmcgYSBkb3duc2FtcGxlZCBkYXRhc2V0LCBzbyB0aGUgbWFqb3JpdHkgb2YgTnVtUmVhZHMgd2lsbCBiZSB6ZXJvLgoKIyMjIENyZWF0ZSBhIGNvdW50IG1hdHJpeAoKTWV0aG9kcyBmb3IgZGV0ZWN0aW5nIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFyZSBsaWtlbHkgdG8gd2FudCBkYXRhIGluIHRoZSBmb3JtIG9mIGEgdGFibGU7IHdoZXJlIGV2ZXJ5IHJvdyBpcyBhIGRpZmZlcmVudCBnZW5lIGFuZCBlYWNoIGNvbHVtbiBpcyBhIHVuaXF1ZSBiaW9sb2dpY2FsIHNhbXBsZS4gQmVmb3JlIHdlIGNhbiBwcm9jZWVkIHdlIHdpbGwgdGhlcmVmb3JlIG5lZWQgdG8gKm1lcmdlKiBvdXIgc2FsbW9uIHJlc3VsdHMgaW50byBhIHNpbmdsZSBvdXRwdXQuIFRoaXMgY2FuIGJlIGRvd24gdXNpbmcgdGhlICpTYWxtb24gcXVhbnRtZXJnZSogdG9vbAoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoqKlJOQSBBbmFseXNpcyoqIC0+ICoqU2FsbW9uIHF1YW50bWVyZ2UqKgo8L2Rpdj4KClVzZSB0aGUgK0luc2VydCBRdWFudCBmaWxlIGFuZCBuYW1lcyBidXR0b24gcmVwZWF0ZWRseSB0byBzZWxlY3QgZWFjaCBvZiB5b3VyICoqR2VuZSBRdWFudGlmaWNhdGlvbioqIG91dHB1dHMuIFRoZSBPbmUtd29yZCBzYW1wbGUgbmFtZXMgdGV4dCBib3ggY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgc2hvcnRlciBjb2x1bW4gbmFtZSBmb3IgZWFjaCBvdXRwdXQuCgpPbmNlIGFsbCB0aGUgR2VuZSBRdWFudGlmaWNhdGlvbiBmaWxlcyBoYXZlIGJlZW4gc2VsZWN0ZWQgdGhlIGRyb3AtZG93biBtZW51IHVuZGVyICoqQ29sdW1ucyoqIHNob3VsZCBiZSBjaGFuZ2VkIGZyb20gTGVuZ3RoIHRvICoqTnVtUmVhZHMqKi4KCkFmdGVyIHRoZSB0b29sIGhhcyBmaW5pc2hlZCB5b3Ugc2hvdWxkIGhhdmUgYSB0YWJsZSB3aXRoIAoKIyMjIEFkZGluZyBleHRyYSBhbm5vdGF0aW9uIHRvIHJlc3VsdHMKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKipUZXh0IE1hbmlwdWxhdGlvbioqIC0+ICoqSm9pbiB0d28gZmlsZXMqKgo8L2Rpdj4KCi0gMXN0IGZpbGU6ICpDb2x1bW4gSm9pbiBvbiBkYXRhLi4uLioKLSBDb2x1bW4gdG8gdXNlIGZyb20gMXN0IGZpbGU6IENvbHVtbiAxCi0gMm5kIGZpbGU6IHJlc3VsdCBmcm9tICphbm5vdGF0ZU15SURzIG9uIGRhdGEuLi4qCi0gQ29sdW1uIHRvIHVzZSBmcm9tIDJuZCBmaWxlOiBDb2x1bW4gMQoKIyMgKiooT3B0aW9uYWwpKiogQWx0ZXJuYXRpdmUgd29ya2Zsb3cgaW52b2x2aW5nIGdlbm9tZSBhbGlnbm1lbnQKCklmIHRpbWUgYWxsb3dzLCB3ZSB3aWxsIGFsc28gZm9sbG93IHRoaXMgc2VjdGlvbgoKIVtdKGh0dHBzOi8vZGF0YWJlYXV0eS5jb20vZmlndXJlcy8yMDE2LTA5LTEzLVJOQS1zZXEtYW5hbHlzaXMvcm5hX3NlcV93b3JrZmxvdy5wbmcpCgpUaGUgd29ya2Zsb3cgdGhhdCBwZW9wbGUgdXNlZCBmb3IgbWFueSB5ZWFycyBpcyBzdW1tYXJpc2VkIGluIHRoaXMgaW1hZ2UgZnJvbSBUaW5nLXlvdSBXYW5nJ3MgW1JOQS1zZXEgZGF0YSBhbmFseXNpcyBwYWdlXShodHRwczovL2RhdGFiZWF1dHkuY29tL2Jsb2cvdHV0b3JpYWwvMjAxNi8wOS8xMy9STkEtc2VxLWFuYWx5c2lzLmh0bWwpLCBhbmQgbWF5IHN0aWxsIGJlIHByZWZlcmFibGUgaWYgeW91ciBhbmFseXNpcyBkb2Vzbid0IGp1c3QgY2FsbCBmb3IgZ2VuZS1sZXZlbCBjb3VudHMuIAo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+CgpNYXBwaW5nIC0+IEhJU0FUMgoKPC9kaXY+CgojIyMjIDEuICBNYXAvYWxpZ24gdGhlIHJlYWRzIHdpdGggSElTQVQyIHRvIHRoZSBoZzM4IHJlZmVyZW5jZSBnZW5vbWUKSW4gdGhlIGxlZnQgdG9vbCBwYW5lbCBtZW51LCB1bmRlciBOR1MgQW5hbHlzaXMsIHNlbGVjdAoqKk1hcHBpbmcgPiBISVNBVDIqKiBhbmQgc2V0IHRoZSBwYXJhbWV0ZXJzIGFzIGZvbGxvd3M6ICAKCi0gKipJcyB0aGlzIHNpbmdsZS1lbmQgb3IgcGFpcmVkLWVuZCBkYXRhPyoqIFNpbmdsZS1lbmQgKGFzIGluZGl2aWR1YWwgZGF0YXNldHMpICAKLSAqKkZBU1RRIGZpbGUqKiAgCihDbGljayBvbiB0aGUgbXVsdGlwbGUgZGF0YXNldHMgaWNvbiBhbmQgc2VsZWN0IGFsbCBmb3VyIG9mIHRoZQpGQVNUUSBmaWxlcykKICAgIC0gYFNSUjcxMDgzODguZmFzdHEuZ3pgCiAgICAtIGBTUlI3MTA4Mzg5LmZhc3RxLmd6YAogICAgLSBgU1JSNzEwODM5Mi5mYXN0cS5nemAKICAgIC0gYFNSUjcxMDgzOTMuZmFzdHEuZ3pgCgotICoqU291cmNlIGZvciB0aGUgcmVmZXJlbmNlIGdlbm9tZSoqIFVzZQpidWlsdC1pbiBnZW5vbWUKLSAqKlNlbGVjdCBhIHJlZmVyZW5jZSBnZW5vbWU6KiogSHVtYW4gRGVjIDIwMTMuIChHUkNoMzgvaGczOCkgKGhnMzgpCi0gVXNlIGRlZmF1bHRzIGZvciB0aGUgb3RoZXIgZmllbGRzCi0gRXhlY3V0ZQoKCgojIyMgUXVhbnRpZmljYXRpb24gKENvdW50aW5nIHJlYWRzIGluIGZlYXR1cmVzKQoKSW4gb3JkZXIgdG8gdGVzdCBmb3IgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24sIHdlIG5lZWQgdG8gY291bnQgdXAgaG93IG1hbnkgdGltZXMgZWFjaCAiZmVhdHVyZSIgaXMgb2JzZXJ2ZWQgaW4gZWFjaCBzYW1wbGUuIFRoZSBnb2FsIG9mIHN1Y2ggb3BlcmF0aW9ucyBpcyB0byBwcm9kdWNlIGEgKmNvdW50IHRhYmxlKiBzdWNoIGFzIHRoYXQgc2hvd24gYmVsb3cuIFdlIGNhbiB0aGVuIGFwcGx5IHN0YXRpc3RpY2FsIHRlc3RzIHRvIHRoZXNlIGRhdGEKCiFbXShtZWRpYS9jb3VudHMucG5nKQoKSFRTZXEtY291bnQgY3JlYXRlcyBhIGNvdW50IG1hdHJpeCB1c2luZyB0aGUgbnVtYmVyIG9mIHRoZSByZWFkcyBmcm9tIGVhY2ggYmFtCmZpbGUgdGhhdCBtYXAgdG8gdGhlIGdlbm9taWMgZmVhdHVyZXMuIEZvciBlYWNoIGZlYXR1cmUgKGEKZ2VuZSBmb3IgZXhhbXBsZSkgYSBjb3VudCBtYXRyaXggc2hvd3MgaG93IG1hbnkgcmVhZHMgd2VyZSBtYXBwZWQgdG8gdGhpcwpmZWF0dXJlLgoKVmFyaW91cyBydWxlcyBjYW4gYmUgdXNlZCB0byBhc3NpZ24gY291bnRzIHRvIGZlYXR1cmVzCgohW10obWVkaWEvaHRzZXEucG5nKQoKVG8gb2J0YWluIHRoZSBjb29yZGluYXRlcyBvZiBlYWNoIGdlbmUsIHdlIGNhbiB1c2UgdGhlIFVDU0MgZ2Vub21lIGJyb3dzZXIgd2hpY2ggaXMgaW50ZWdyYXRlZCBpbnRvIEdhbGF4eS4KCiMjIyBPYnRhaW5pbmcgZ2VuZSBjb29yZGluYXRlcwoKW0Vuc2VtYmxdKGh0dHA6Ly9tLmVuc2VtYmwub3JnL2luZm8vZGF0YS9mdHAvaW5kZXguaHRtbCkgCgojIyMgQ291bnRpbmcgcmVhZHMgaW4gZ2VuZXMKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKipSTkEgQW5hbHlzaXMgPiBodHNlcS1jb3VudCoqCjwvZGl2PgoKMS4gIFVzZSBIVFNlcS1jb3VudCB0byBjb3VudCB0aGUgbnVtYmVyIG9mIHJlYWRzIGZvciBlYWNoIGZlYXR1cmUuICAKICAgIEluIHRoZSBsZWZ0IHRvb2wgcGFuZWwgbWVudSwgdW5kZXIgTkdTIEFuYWx5c2lzLCBzZWxlY3QKICAgICoqTkdTIEFuYWx5c2lzID4gaHRzZXEtY291bnQqKiBhbmQgc2V0IHRoZSBwYXJhbWV0ZXJzIGFzIGZvbGxvd3M6ICAKICAgIC0gKipBbGlnbmVkIFNBTS9CQU0gZmlsZSoqICAKICAgICAgKFNlbGVjdCBvbmUgb2YgZm91ciBiYW0gZmlsZXMsIG9yIGFsbCBmb3VyIHVzaW5nIHRoZSBtdWx0aXBsZSBkYXRhc2V0cyBvcHRpb24pCiAgICAtICoqR0ZGIGZpbGUqKiBVQ1NDIE1haW4gb24gTW91c2U6bmNiaVJlZlNlcSAoZ2Vub21lKQogICAgLSBVc2UgZGVmYXVsdHMgZm9yIHRoZSBvdGhlciBmaWVsZHMKICAgIC0gRXhlY3V0ZQoyLiAgUmVwZWF0IGZvciB0aGUgcmVtYWluaW5nIGJhbSBmaWxlcyBpZiBydW5uaW5nIG9uIGVhY2ggYmFtIHNlcGFyYXRlbHkuCjMuICBUbyBtYWtlIHRoaW5ncyBlYXNpZXIgdG8gdHJhY2ssIHJlbmFtZSB0aGUgaHQtc2VxIG91dHB1dCBmb3IgZWFjaCBzYW1wbGUgdG8gY29udGFpbiB0aGUgY29ycmVzcG9uZGluZyBzYW1wbGUgbmFtZSAoZS5nLiBTUlIxNTUyNDQ0Lmh0c2VxKS4gKipEbyBub3QgcmVuYW1lIHRoZSBvdXRwdXRzIHRoYXQgaGF2ZSAiKG5vIGZlYXR1cmUpIiBpbiB0aGVpciBuYW1lKioKCiMjIyBDcmVhdGUgYSBjb3VudCBtYXRyaXgKClRoZSBodHNlcSB0b29sIGlzIGRlc2lnbmVkIHRvIHByb2R1Y2UgYSBzZXBhcmF0ZSB0YWJsZSBvZiBjb3VudHMgZm9yIGVhY2ggc2FtcGxlLiBUaGlzIGlzIG5vdCBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBvdGhlciB0b29scyBzdWNoIGFzIERlZ3VzdCAoc2VlIG5leHQgc2VjdGlvbikgd2hpY2ggcmVxdWlyZSB0aGUgY291bnRzIHRvIGJlIHByZXNlbnRlZCBpbiBhIGRhdGEgbWF0cml4IHdoZXJlIGVhY2ggcm93IGlzIGEgZ2VuZSBhbmQgZWFjaCBjb2x1bW4gaXMgYSBwYXJ0aWN1bGFyIHNhbXBsZSBpbiB0aGUgZGF0YXNldC4KCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKkNvbGxlY3Rpb24gT3BlcmF0aW9ucyAtPiBDb2x1bW4gSm9pbiogb24gQ29sbGVjdGlvbnMKPC9kaXY+CgotIEluIHRoZSAqVGFidWxhciBGaWxlcyogc2VjdGlvbiwgc2VsZWN0IHRoZSBgaHQtc2VxYCBjb3VudCBmaWxlcyBmcm9tIHlvdXIgaGlzdG9yeSAqU1JSMTU1MjQ0NC5odHNlcSosICpTUlIxNTUyNDUwKiwgZXRjLi4uIEhvbGRpbmcgdGhlIENUUkwga2V5IGFsbG93cyBtdWx0aXBsZSBmaWxlcyB0byBiZSBzZWxlY3RlZAotIEtlZXAgKklkZW50aWZpZXIgY29sdW1uKiBhcyBgMWAKCgoKCiMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gdXNpbmcgRGVndXN0CgpEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBpcyBwb3NzaWJsZSB1c2luZyBHYWxheHkgdXNpbmcgdGhlIERFU2VxMiB0b29sIChmb3IgZXhhbXBsZSkuIEhvd2V2ZXIsIG91ciBwYXJ0aWN1bGFyIHJlY29tbWVuZGF0aW9uIGlzIHRvIHVzZSBEZWd1c3QgZm9yIGEgbW9yZSBpbnRlcmFjdGl2ZSBleHBlcmllbmNlLiBGb3IgdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGJlIHVzaW5nIGNvdW50cyBnZW5lcmF0ZWQgb24gdGhlICpmdWxsIGRhdGFzZXQqLCByYXRoZXIgdGhhbiB0aGUgKmRvd25zYW1wbGVkKiBkYXRhIGFuYWx5c2VkIGluIHRoZSBwcmV2aW91cyBzZWN0aW9uLiBUaGVzZSBjb3VudHMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgZmlsZSBgR1NFMTE0MDEzX3NhbG1vbl9jb3VudHMuY3N2YC4KCgojIyBEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgoKVGhlIHRlcm0gKmRpZmZlcmVudGlhbCBleHByZXNzaW9uKiB3YXMgZmlyc3QgdXNlZCB0byByZWZlciB0byB0aGUgcHJvY2VzcyBvZiBmaW5kaW5nIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZ2VuZXMgZnJvbSBhICptaWNyb2FycmF5KiBnZW5lIGV4cHJlc3Npb24gc3R1ZHkuCgohW10obWVkaWEvZGVfZXhwbGFpbmVkLnBuZykKCgpTdWNoIG1ldGhvZHMgd2VyZSBkZXZlbG9wZWQgb24gdGhlIHByZW1pc2UgdGhhdCBtaWNyb2FycmF5IGV4cHJlc3Npb24gdmFsdWVzIGFyZSBhcHByb3hpbWF0ZWx5ICpub3JtYWxseS1kaXN0cmlidXRlZCogd2hlbiBhcHByb3ByaWF0ZWx5IHRyYW5zZm9ybWVkIChlLmcuIGJ5IHVzaW5nIGEgbG9nJF8yJCB0cmFuc2Zvcm1hdGlvbikgc28gdGhhdCBhIG1vZGlmaWVkIHZlcnNpb24gb2YgdGhlIHN0YW5kYXJkICp0LXRlc3QqIGNhbiBiZSB1c2VkLiBUaGUgc2FtZSB0ZXN0IGlzIGFwcGxpZWQgdG8gZWFjaCBnZW5lIHVuZGVyIGludmVzdGlnYXRpb24geWllbGRpbmcgYSAqdGVzdCBzdGF0aXN0aWMqLCAqZm9sZC1jaGFuZ2UqIGFuZCAqcC12YWx1ZSouIFNpbWlsYXIgbWV0aG9kcyBoYXZlIGJlZW4gYWRhcHRlZCB0byBSTkEtc2VxIGRhdGEgdG8gYWNjb3VudCBmb3IgdGhlIGZhY3QgdGhhdCB0aGUgZGF0YSBhcmUgKmNvdW50LWJhc2VkKiBhbmQgZG8gbm90IGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24uCgoKIVtdKG1lZGlhL3JuYV9hZHZhbmNlZF9kZWd1c3RfMS5wbmcpCgo8Zm9udCBzaXplPSI4Ij5baHR0cDovL2RlZ3VzdC5lcmMubW9uYXNoLmVkdS9dKGh0dHA6Ly9kZWd1c3QuZXJjLm1vbmFzaC5lZHUvKTwvZm9udD4KCmBEZWd1c3RgIGlzIGEgd2ViIHRvb2wgdGhhdCBjYW4gYW5hbHlzZSB0aGUgY291bnRzIGZpbGVzIHByb2R1Y2VkIGluIHRoZSBzdGVwIGFib3ZlLCB0byB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uLiBJdCBvZmZlcnMgYW5kIGludGVyYWN0aXZlIHZpZXcgb2YgdGhlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIHJlc3VsdHMKClRoZSBpbnB1dCBmaWxlIGlzIGEgY291bnQgbWF0cml4IHdoZXJlIGVhY2ggcm93IGlzIGEgbWVhc3VyZWQgZ2VuZSwgYW5kIGVhY2ggY29sdW1uIGlzIGEgZGlmZmVyZW50IGJpb2xvZ2ljYWwgc2FtcGxlLiBXaXRoaW4gdGhlIHRvb2wgd2UgY2FuIGNvbmZpZ3VyZSB3aGljaCBzYW1wbGVzIGJlbG9uZyB0byB0aGUgZGlmZmVyZW50IGJpb2xvZ2ljYWwgZ3JvdXBzIG9mIGludGVyZXN0LgoKUmVhZCBjb3VudHMgaGF2ZSB0byBiZSBub3JtYWxpc2VkIGZpcnN0IHByaW9yIHRvIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIHRlc3RpbmcuIFRoZXJlIGFyZSB0d28gbWFpbiBiaWFzZXMgdGhhdCBuZWVkIHRvIGJlIGFjY291bnRlZCBmb3I6LQoKLSBzaXplIG9mIGdlbmUKICAgICsgKmxvbmdlciogZ2VuZXMgd2lsbCBoYXZlIG1vcmUgcmVhZHMgYXNzaWduZWQgdG8gdGhlbQotIGxpYnJhcnkgc2l6ZQogICAgKyBhIHNhbXBsZSB0aGF0IGlzIHNlcXVlbmNlZCB0byBhIGhpZ2hlciBkZXB0aCB3aWxsIHJlY2VpdmUgbW9yZSByZWFkcwogIApIb3dldmVyLCBSLWJhc2VkIG1ldGhvZHMgc3VjaCBhcyBgZWRnZVJgIChpbXBsZW1lbnRlZCBpbiBEZWd1c3QpIGFuZCBgREVTZXEyYCBoYXZlIHRoZWlyIG93biBtZXRob2Qgb2Ygbm9ybWFsaXNpbmcgY291bnRzLiBZb3Ugd2lsbCBwcm9iYWJseSBlbmNvdW50ZXIgb3RoZXIgbWV0aG9kcyBvZiBub3JtYWxpc2luZyBSTkEtc2VxIHJlYWRzIHN1Y2ggYXMgKlJQS00qLCAqQ1BNKiwgKlRQTSogZXRjLiBbVGhpcyBibG9nXShodHRwczovL3d3dy5ybmEtc2VxYmxvZy5jb20vcnBrbS1mcGttLWFuZC10cG0tY2xlYXJseS1leHBsYWluZWQvKSBwcm92aWRlcyBhIG5pY2UgZXhwbGFuYXRpb24gb2YgdGhlIGN1cnJlbnQgdGhpbmtpbmcuIEFzIHBhcnQgb2YgdGhlIGBEZWd1c3RgIG91dHB1dCwgeW91IGhhdmUgdGhlIG9wdGlvbiBvZiBkb3dubG9hZGluZyBub3JtYWxpc2VkIGNvdW50cyBpbiB2YXJpb3VzIGZvcm1hdHMuIFNvbWUgb3RoZXIgb25saW5lIHZpc3VhbGlzYXRpb24gdG9vbHMgcmVxdWlyZSBub3JtYWxpc2VkIGNvdW50cyBhcyBpbnB1dCwgc28gaXQgaXMgZ29vZCB0byBoYXZlIHRoZXNlIHRvLWhhbmQuCgoKIyMjIFVwbG9hZGluZyB0aGUgY291bnQgbWF0cml4IHRvIERlZ3VzdAoKCi0gRnJvbSB0aGUgbWFpbiBkZWd1c3QgcGFnZSwgY2xpY2sgKlVwbG9hZCB5b3VyIGNvdW50cyBmaWxlKgotIENsaWNrIG9uIEJyb3dzZQotIFNlbGVjdCB0aGUgbG9jYXRpb24gb2YgdGhlIGZpbGUgYEdTRTExNDAxM19zYWxtb25fY291bnRzLmNzdmAsIGFuZCBjbGljayAqT3BlbiouCi0gQ2xpY2sgKlVwbG9hZCoKLSBBIENvbmZpZ3VyYXRpb24gcGFnZSB3aWxsIGFwcGVhci4KCiFbXShtZWRpYS9kZWd1c3RfY29uZmlnLnBuZykKCi0gRm9yIE5hbWUgdHlwZSAiKkdTRTExNDAxMyoiIChvciB3aGF0ZXZlciB5b3Ugd2FudCB0byBjYWxsIHRoZSBhbmFseXNpcykKLSBGb3IgSW5mbyBjb2x1bW5zIHNlbGVjdCAqU1lNQk9MKgotIENsaWNrIEFkZCBjb25kaXRpb24KICAgICsgUmVmZXJyaW5nIHRvIHRoZSBleHBlcmltZW50IGRlc2lnbiAoYmVsb3cpLCBzZWxlY3QgdGhlIERNU08gc2FtcGxlcyBhbmQgY2FsbCB0aGUgY29uZGl0aW9uIERNU08KICAgICsgUmVwZWF0IGZvciB0aGUgSVRSQUNPTkFaT0xFIHNhbXBsZXMKLSBTYXZlIHRoZSBzZXR0aW5ncyBhbmQgdGhlbiBWaWV3IHRoZSByZXN1bHRzCgpydW4JfCBuYW1lCXwgY2VsbF9saW5lCXwgY29uZGl0aW9uCi0tLS18LS0tLS0tLXwtLS0tLS0tLS0tLXwtLS0tLS0tLS0gClNSUjcxMDgzODgJfCBIVDU1X0NPTlRfMQl8IEhUNTUJfCBETVNPClNSUjcxMDgzODkJfCBIVDU1X0NPTlRfMgl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTAJfCBIVDU1X0NPTlRfMwl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTEJfCBIVDU1X0NPTlRfNAl8IEhUNTUJfCBETVNPClNSUjcxMDgzOTIJfCBIVDU1X0lUUkFfMQl8IEhUNTUJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODM5Mwl8IEhUNTVfSVRSQV8yCXwgSFQ1NQl8IElUUkFDT05BWk9MRQpTUlI3MTA4Mzk0CXwgSFQ1NV9JVFJBXzMJfCBIVDU1CXwgSVRSQUNPTkFaT0xFClNSUjcxMDgzOTUJfCBIVDU1X0lUUkFfNAl8IEhUNTUJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODM5Ngl8IFNXOTQ4X0NPTlRfMSB8IFNXOTQ4CXwgRE1TTwpTUlI3MTA4Mzk3CXwgU1c5NDhfQ09OVF8yIHwgU1c5NDgJfCBETVNPClNSUjcxMDgzOTgJfCBTVzk0OF9DT05UXzMgfCBTVzk0OAl8IERNU08KU1JSNzEwODM5OQl8IFNXOTQ4X0NPTlRfNCB8IFNXOTQ4CXwgRE1TTwpTUlI3MTA4NDAwCXwgU1c5NDhfSVRSQV8xIHwgU1c5NDgJfCBJVFJBQ09OQVpPTEUKU1JSNzEwODQwMQl8IFNXOTQ4X0lUUkFfMiB8IFNXOTQ4CXwgSVRSQUNPTkFaT0xFClNSUjcxMDg0MDIJfCBTVzk0OF9JVFJBXzMgfCBTVzk0OAl8IElUUkFDT05BWk9MRQpTUlI3MTA4NDAzCXwgU1c5NDhfSVRSQV80IHwgU1c5NDgJfCBJVFJBQ09OQVpPTEUKCgoKIyMjIE92ZXJ2aWV3IG9mIERlZ3VzdCBzZWN0aW9ucwoKLSBUb3AgYmxhY2sgcGFuZWwgd2l0aCBDb25maWd1cmUgc2V0dGluZ3MgYXQgcmlnaHQuCi0gTGVmdDogQ29uZGl0aW9uczogRE1TTyBhbmQgSVRSQUNPTkFaT0xFLgotIFRvcCBjZW50cmU6IFBsb3RzLCB3aXRoIG9wdGlvbnMgYXQgcmlnaHQuCi0gV2hlbiBlaXRoZXIgb2YgdGhlIGV4cHJlc3Npb24gcGxvdHMgYXJlIHNlbGVjdGVkLCBhIGhlYXRtYXAgYXBwZWFycyBiZWxvdy4KLSBBIHRhYmxlIG9mIGdlbmVzIChvciBmZWF0dXJlcyk7IGV4cHJlc3Npb24gaW4gdHJlYXRtZW50IHJlbGF0aXZlIHRvIGNvbnRyb2wgKFRyZWF0bWVudCBjb2x1bW4pOyBhbmQgc2lnbmlmaWNhbmNlIChGRFIgY29sdW1uKS4KCigqKk5vdCB0aGF0IHRoZSBzY3JlZW5zaG90cyBhcmUgZm9yIGlsbHVzdHJhdGlvbiBwdXJwb3NlcyBhbmQgdGFrZW4gZnJvbSBhIGRpZmZlcmVudCBkYXRhc2V0IHRvIHRoYXQgYmVpbmcgYW5hbHlzZWQgaW4gdGhlIHR1dG9yaWFsKiopCgohW10oaHR0cDovL3NlcHNpcy1vbWljcy5naXRodWIuaW8vdHV0b3JpYWxzL21vZHVsZXMvZGdlL2ltYWdlcy9pbWFnZTEyLnBuZykKCgojIyMgTUEtcGxvdAoKIVtdKG1lZGlhL2RlZ3VzdF9tYS5wbmcpCgpFYWNoIGRvdCBzaG93cyB0aGUgY2hhbmdlIGluIGV4cHJlc3Npb24gaW4gb25lIGdlbmUuCgotIFRoZSBhdmVyYWdlIGV4cHJlc3Npb24gKG92ZXIgYm90aCBjb25kaXRpb24gYW5kIHRyZWF0bWVudCBzYW1wbGVzKSBpcyByZXByZXNlbnRlZCBvbiB0aGUgeC1heGlzLgogICAgKyBQbG90IHBvaW50cyBzaG91bGQgYmUgc3ltbWV0cmljYWwgYXJvdW5kIHRoZSB4LWF4aXMuCiAgICArIFdlIGNhbiBzZWUgdGhhdCBtYW55IGdlbmVzIGFyZSBleHByZXNzZWQgYXQgYSBsb3cgbGV2ZWwsIGFuZCBzb21lIGFyZSBoaWdobHkgZXhwcmVzc2VkLgotIFRoZSBmb2xkIGNoYW5nZSBpcyByZXByZXNlbnRlZCBvbiB0aGUgeSBheGlzLgogICAgKyBJZiBleHByZXNzaW9uIGlzIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGJldHdlZW4gYmF0Y2ggYW5kIGNoZW0sIHRoZSBkb3RzIGFyZSByZWQuIElmIG5vdCwgdGhleSBhcmUgYmx1ZS4gKEluIERlZ3VzdCwgc2lnbmlmaWNhbnQgbWVhbnMgRkRSIDwwLjA1KS4KICAgICsgQXQgbG93IGxldmVscyBvZiBnZW5lIGV4cHJlc3Npb24gKGxvdyB2YWx1ZXMgb2YgdGhlIHggYXhpcyksIGZvbGQgY2hhbmdlcyBhcmUgbGVzcyBsaWtlbHkgdG8gYmUgc2lnbmlmaWNhbnQuCgpDbGljayBvbiB0aGUgZG90IHRvIHNlZSB0aGUgZ2VuZSBuYW1lLgoKIyMjIFBhcmFsbGVsIGNvb3JkaW5hdGVzIGFuZCBoZWF0bWFwCgohW10obWVkaWEvZGVndXN0X3BhcmFsbGVsX2hlYXRtYXAucG5nKQoKRWFjaCBsaW5lIHNob3dzIHRoZSBjaGFuZ2UgaW4gZXhwcmVzc2lvbiBpbiBvbmUgZ2VuZSwgYmV0d2VlbiBjb250cm9sIGFuZCB0cmVhdG1lbnQuCgotIEdvIHRvIE9wdGlvbnMgYXQgdGhlIHJpZ2h0LgogICAgKyBGb3IgRkRSIGN1dC1vZmYgc2V0IGF0IDAuMDAxLgogICAgKyBUaGlzIGlzIGEgc2lnbmlmaWNhbmNlIGxldmVsIChhbiBhZGp1c3RlZCBwIHZhbHVlKS4gV2Ugd2lsbCBzZXQgaXQgcXVpdGUgbG93IGluIHRoaXMgZXhhbXBsZSwgdG8gZW5zdXJlIHdlIG9ubHkgZXhhbWluZSBrZXkgZGlmZmVyZW5jZXMuCi0gTG9vayBhdCB0aGUgUGFyYWxsZWwgQ29vcmRpbmF0ZXMgcGxvdC4gVGhlcmUgYXJlIHR3byBheGVzOgogICAgKyBMZWZ0OiBDb250cm9sOiBHZW5lIGV4cHJlc3Npb24gaW4gdGhlIGNvbnRyb2wgc2FtcGxlcy4gQWxsIHZhbHVlcyBhcmUgc2V0IGF0IHplcm8uCiAgICArIFJpZ2h0OiBUcmVhdG1lbnQgR2VuZSBleHByZXNzaW9uIGluIHRoZSB0cmVhdG1lbnQgc2FtcGxlcywgcmVsYXRpdmUgdG8gZXhwcmVzc2lvbiBpbiB0aGUgY29udHJvbC4KLSBUaGUgYmxvY2tzIG9mIGJsdWUgYW5kIHJlZCB1bmRlcm5lYXRoIHRoZSBwbG90IGFyZSBjYWxsZWQgYSBoZWF0bWFwLgogICAgKyBFYWNoIGJsb2NrIGlzIGEgZ2VuZS4gQ2xpY2sgb24gYSBibG9jayB0byBzZWUgaXRzIGxpbmUgaW4gdGhlIHBsb3QgYWJvdmUuCiAgICArIExvb2sgYXQgdGhlIHJvdyBmb3IgdGhlIGNoZW0uIFJlbGF0aXZlIHRvIGJhdGNoLCBnZW5lcyBleHByZXNzZWQgbW9yZSBhcmUgcmVkOyBnZW5lcyBleHByZXNzZWQgbGVzcyBhcmUgYmx1ZS4KCiMjIyBUYWJsZSBvZiBnZW5lcwoKIVtdKG1lZGlhL2RlZ3VzdF9nZW5lX3RhYmxlLnBuZykKClRhYmxlIG9mIGdlbmVzCgotIGdlbmVfaWQ6IG5hbWVzIG9mIGdlbmVzLiBOb3RlIHRoYXQgZ2VuZSBuYW1lcyBhcmUgc29tZXRpbWVzIHNwZWNpZmljIHRvIGEgc3BlY2llcywgb3IgdGhleSBtYXkgYmUgb25seSBuYW1lZCBhcyBhIGxvY3VzIElEIChhIGNocm9tb3NvbWFsIGxvY2F0aW9uIHNwZWNpZmllZCBpbiB0aGUgZ2Vub21lIGFubm90YXRpb24pLgotIEZEUjogRmFsc2UgRGlzY292ZXJ5IFJhdGUuIFRoaXMgaXMgYW4gYWRqdXN0ZWQgcCB2YWx1ZSB0byBzaG93IHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlIGRpZmZlcmVuY2UgaW4gZ2VuZSBleHByZXNzaW9uIGJldHdlZW4gdHdvIGNvbmRpdGlvbnMuIENsaWNrIG9uIGNvbHVtbiBoZWFkaW5ncyB0byBzb3J0LiBCeSBkZWZhdWx0LCB0aGlzIHRhYmxlIGlzIHNvcnRlZCBieSBGRFIuCi0gYmFzYWwgYW5kIGx1bWluYWw6IGxvZzIoRm9sZCBDaGFuZ2UpIG9mIGdlbmUgZXhwcmVzc2lvbi4gVGhlIGRlZmF1bHQgZGlzcGxheSBpcyBvZiBmb2xkIGNoYW5nZSBpbiB0aGUgdHJlYXRtZW50IHJlbGF0aXZlIHRvIHRoZSBjb250cm9sLiBUaGVyZWZvcmUsIHZhbHVlcyBpbiB0aGUgYmF0Y2ggY29sdW1uIGFyZSB6ZXJvLiBUaGlzIGNhbiBiZSBjaGFuZ2VkIGluIHRoZSBPcHRpb25zIHBhbmVsIGF0IHRoZSB0b3AgcmlnaHQuCiAgICArIEluIHNvbWUgY2FzZXMsIGEgbGFyZ2UgZm9sZCBjaGFuZ2Ugd2lsbCBiZSBtZWFuaW5nZnVsIGJ1dCBpbiBvdGhlcnMsIGV2ZW4gYSBzbWFsbCBmb2xkIGNoYW5nZSBjYW4gYmUgaW1wb3J0YW50IGJpb2xvZ2ljYWxseS4KClRoZSB0YWJsZSBjYW4gYmUgc29ydGVkIGFjY29yZGluZyB0byBhbnkgb2YgdGhlIGNvbHVtbnMgKGUuZy4gZm9sZC1jaGFuZ2Ugb3IgcC12YWx1ZSkKCgojIyMgRG93bmxvYWQgYW5kIFIgY29kZQoKQWJvdmUgdGhlIGdlbmVzIHRhYmxlIGlzIHRoZSBvcHRpb24gdG8gZG93bmxvYWQgdGhlIHJlc3VsdHMgb2YgdGhlIGN1cnJlbnQgYW5hbHlzaXMgdG8gYSBjc3YgZmlsZS4gWW91IGNhbiBhbHNvIGRvd25sb2FkIHRoZSAqUiogY29kZSByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIGFuYWx5c2lzIGJ5IGNsaWNraW5nIHRoZSAqU2hvdyBSIGNvZGUqIGJveCB1bmRlcm5lYXRoIHRoZSBPcHRpb25zIGJveC4KClBsb3RzIHN1Y2ggYXMgdGhlIE1EUywgTUEgYW5kIGhlYXRtYXAgY2FuIGFsc28gYmUgZXhwb3J0ZWQgYnkgcmlnaHQtY2xpY2tpbmcgb24gdGhlIHBsb3QuCgoKIyMjIE1EUyBwbG90CgpUaGlzIGlzIGEgbXVsdGlkaW1lbnNpb25hbCBzY2FsaW5nIHBsb3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgdmFyaWF0aW9uIGJldHdlZW4gc2FtcGxlcy4gSXQgaXMgYSBzaW1pbGFyIGNvbmNlcHQgdG8gYSBQcmluY2lwYWwgQ29tcG9uZW50cyBBbmFseXNpcyAoUENBKSBwbG90LiBUaGUgeC1heGlzIGlzIHRoZSBkaW1lbnNpb24gd2l0aCB0aGUgaGlnaGVzdCBtYWduaXR1ZGUuIEluIGEgc3RhbmRhcmQgY29udHJvbC90cmVhdG1lbnQgc2V0dXAsIHNhbXBsZXMgc2hvdWxkIGJlIHNwbGl0IGFsb25nIHRoaXMgYXhpcy4gQSBkZXNpcmFibGUgcGxvdCBpcyBzaG93biBiZWxvdzotCgohW10obWVkaWEvZGVndXN0X21kcy5wbmcpCgojIyMgRXhlcmNpc2UKCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4KKipRdWVzdGlvbjoqKiBJdCBzZWVtcyB0aGF0IHRoZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcyBpcyBkZXRlY3RpbmcgbG90cyBvZiBnZW5lcy4gSG93ZXZlciwgZG9lcyB0aGlzIHRlbGwgdGhlIHdob2xlIHN0b3J5IGFib3V0IHRoZSBkYXRhc2V0PyBXaGF0IGRvIHlvdSB0aGluayBpcyB0aGUgbWFpbiBmYWN0b3Igc2VwYXJhdGluZyBzYW1wbGVzIG9uIHRoZSB4LWF4aXMsIGFuZCB0aHVzIGV4cGxhaW5pbmcgdGhlIG1vc3QgdmFyaWF0aW9uIGluIHRoZSBkYXRhPwoKPC9kaXY+CgoKCiMjIE1vZGlmeWluZyB0aGUgYW5hbHlzaXMKCldlIHdpbGwgbm93IHJlcGVhdCB0aGUgYW5hbHlzaXMsIGJ1dCBvbmx5IGZvciBzYW1wbGVzIGZyb20gdGhlICpIVDU1KiBjZWxsLWxpbmUuIFRoZSBjb3JyZWN0IGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgYW5hbHlzaXMgaXMgc2hvd24gYmVsb3c6LQoKIVtdKG1lZGlhL2RlZ3VzdF9odDU1LlBORykKCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4KKipFeGVyY2lzZSoqOiBIb3cgbWFueSBnZW5lcyBhcmUgZGlmZmVyZW50aWFsbHktZXhwcmVzc2VkIHdpdGggYW4gRkRSIDwgMC4wNSBhbmQgYWJzIGxvZ0ZDID4gMS4gRG93bmxvYWQgdGhpcyBmaWxlIGFuZCByZW5hbWUgaXQgdG8gYEhUNTUuSVRSQUNPTkFaT0xFX3ZzX0RNU08uY3N2YC4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+CioqRXhlcmNpc2U6KiogUmVzdCB0aGUgRkRSIGN1dC1vZmYgYW5kIGFicyBMb2dGQyBjdXRvZmZzIGJhY2sgdG8gZGVmYXVsdCBhbmQgKmRvd25sb2FkKiB0aGUgZmlsZSBhbmQgcmVuYW1lIHRvIGBiYWNrZ3JvdW5kLmNzdmAuIFdlIHdpbGwgdXNlIHRoaXMgbGF0ZXIuCjwvZGl2PgoKPGRpdiBjbGFzcz0iZXhlcmNpc2UiPgoqKkV4ZXJjaXNlKio6IFJlcGVhdCB0aGUgYW5hbHlzaXMgZm9yIFNXOTQ4IHNhbXBsZXMgYW5kIGRvd25sb2FkIHRoZSB0YWJsZSBvZiBkaWZmZXJlbnRpYWxseS1leHByZXNzZWQgcmVzdWx0cyAoc2FtZSBGRFIgYW5kIGxvZyBmb2xkLWNoYW5nZSkgdG8gYFNXOTQ4LklUUkFDT05BWk9MRV92c19ETVNPLmNzdmAKPC9kaXY+CgoKCiMjIyBGaWxlIERvd25sb2FkcwoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgpJZiB5b3UgZGlkbid0IG1hbmFnZSB0byBjb21wbGV0ZSB0aGVzZSBhbmFseXNlcywgeW91IGNhbiBkb3dubG9hZCB0aGUgZmlsZXMgZnJvbSBoZXJlIGJ5IHJpZ2h0LWNsaWNraW5nIG9uIGVhY2ggbGluayBhbmQgc2VsZWN0aW5nICJTYXZlIExpbmsgYXMiIChvciBlcXVpdmFsZW50KS4gVGhleSBhcmUgYWxzbyBhdmFpbGFibGUgaW4gdGhlIGNvdXJzZSBnb29nbGUgZHJpdmUuCgotIFtIVDU1LklUUkFDT05BWk9MRV92c19ETVNPLmNzdl0oSFQ1NS5JVFJBQ09OQVpPTEVfdnNfRE1TTy5jc3YpCi0gW1NXOTQ4LklUUkFDT05BWk9MRV92c19ETVNPLmNzdl0oU1c5NDguSVRSQUNPTkFaT0xFX3ZzX0RNU08uY3N2KQotIFtiYWNrZ3JvdW5kLmNzdl0oYmFja2dyb3VuZC5jc3YpCgo8L2Rpdj4KCiMjIyBPdmVybGFwcGluZyBHZW5lIExpc3RzCgpXZSBtaWdodCBzb21ldGltZXMgd2FudCB0byBjb21wYXJlIHRoZSBsaXN0cyBvZiBnZW5lcyB0aGF0IHdlIGlkZW50aWZ5IHVzaW5nIGRpZmZlcmVudCBtZXRob2RzLCBvciBnZW5lcyBpZGVudGlmaWVkIGZyb20gbW9yZSB0aGFuIG9uZSBjb250cmFzdC4gSW4gb3VyIGV4YW1wbGUgZGF0YXNldCB3ZSBjYW4gY29tcGFyZSB0aGUgZ2VuZXMgaW4gdGhlIGNvbnRyYXN0IG9mIElUUkFDT05BWk9MRSB2cyBETVNPIGluIEhUNTUgYW5kIFNXOTQ4IGNlbGxzCgpUaGUgd2Vic2l0ZSAqdmVubnkqIHByb3ZpZGVzIGEgcmVhbGx5IG5pY2UgaW50ZXJmYWNlIGZvciBkb2luZyB0aGlzLgoKIVtdKG1lZGlhL3Zlbm55X2NvbmZpZy5wbmcpCgotIE9wZW4gYm90aCB5b3VyICpIVDU1OiBJVFJBQ09OQVpPTEUgdnMgRE1TTyogYW5kICpTVzk0ODogSVRSQUNPTkFaT0xFIHZzIERNU08qIHJlc3VsdHMgZmlsZXMgaW4gRXhjZWwKLSBHbyB0byB0aGUgdmVubnkgd2Vic2l0ZQogICAgKyBodHRwOi8vYmlvaW5mb2dwLmNuYi5jc2ljLmVzL3Rvb2xzL3Zlbm55LwotIENvcHkgdGhlIG5hbWVzIG9mIGdlbmVzIHdpdGggYWRqdXN0ZWQgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNSBpbiB0aGUgSFQ1NSBhbmFseXNpcyBpbnRvIHRoZSAqKkxpc3QgMSoqIGJveCBvbiB0aGUgdmVubnkgd2Vic2l0ZS4gKipMaXN0IDEqKiBjYW4gYmUgcmVuYW1lZCB0byAqSFQ1NSoKICAgICsgKllvdSBjYW4gc2VsZWN0IGFsbCBlbnRyaWVzIGluIGEgY29sdW1uIHdpdGggdGhlIHNob3J0Y3V0IENUUkwgKyBTUEFDRSoKLSBDb3B5IHRoZSBuYW1lcyBvZiBnZW5lcyB3aXRoIGFkanVzdGVkIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUgaW4gdGhlIFNXOTQ4IGFuYWx5c2lzIGludG8gdGhlICoqTGlzdCAyKiogYm94IG9uIHRoZSB2ZW5ueSB3ZWJzaXRlLiAqKkxpc3QgMioqIGNhbiBiZSByZW5hbWVkIHRvICoqU1c5NDgqKgotIHZlbm55IHNob3VsZCBub3cgcmVwb3J0IHRoZSBudW1iZXIgb2YgZ2VuZXMgZm91bmQgaW4gZWFjaCBsaXN0LCB0aGUgc2l6ZSBvZiB0aGUgaW50ZXJzZWN0aW9uLCBhbmQgZ2VuZXMgdW5pcXVlIHRvIGVhY2ggbWV0aG9kCgojIyMgUmVmaW5lZCBhbmFseXNpcwoKVGhlIGZpbmFsIGFuYWx5c2lzIHdlIHdpbGwgcGVyZm9ybSBpcyB0byBpbmNsdWRlIGFsbCB0aGUgc2FtcGxlcywgYnV0IGNvcnJlY3QgZm9yIHRoZSBkaWZmZXJlbmNlcyBpbiBjZWxsLWxpbmUuIFRoaXMgaXMgYWNoaWV2ZWQgYnkgdGVsbGluZyBEZWd1c3QgYWJvdXQgdGhlICpoaWRkZW4gZmFjdG9ycyogaW4gb3VyIGRhdGFzZXQuIFRoZSBoaWRkZW4gZmFjdG9yIGluIHRoaXMgZGF0YXNldCBpcyB3aGV0aGVyIHRoZSBzYW1wbGUgaXMgZnJvbSB0aGUgKipIVDU1Kiogb3IgKipTVzk0OCoqIHNhbXBsZXMuIEhvd2V2ZXIsIHdlIG9ubHkgbmVlZCB0byBzcGVjaWZ5IHdoaWNoIHNhbXBsZXMgYXJlIGZyb20gSFQ1NS4gT3RoZXIgaGlkZGVuIGZhY3RvcnMgeW91IG1pZ2h0IG5lZWQgdG8gaW5jbHVkZSBjb3VsZCBiZSAoZGVwZW5kaW5nIG9uIHRoZSBNRFMgcGxvdCkgOi0KCi0gc2FtcGxlIGJhdGNoCi0gZ2VuZGVyCgpTZWUgYmVsb3cgZm9yIHRoZSBjb3JyZWN0IGNvbmZpZ3VyYXRpb24gdG8gaW5jbHVkZSB0aGUgaGlkZGVuIGZhY3RvcnMuCgo8aW1nIHNyYz0ibWVkaWEvaGlkZGVuX2ZhY3Rvci5wbmciLz4KCiMgRW5yaWNobWVudCBhbmQgcGF0aHdheXMgYW5hbHlzaXMKCkluIHRoZSBlYXJseSBkYXlzIG9mIG1pY3JvYXJyYXkgYW5hbHlzaXMsIHBlb3BsZSB3ZXJlIGhhcHB5IGlmIHRoZXkgZ290IGEgaGFuZGZ1bCBvZiBkaWZmZXJlbnRpYWxseS1leHByZXNzZWQgZ2VuZXMgdGhhdCB0aGV5IGNvdWxkIHZhbGlkYXRlIG9yIGZvbGxvdy11cC4gSG93ZXZlciwgd2l0aCBsYXRlciB0ZWNobm9sb2dpZXMgKGFuZCBkZXBlbmRpbmcgb24gdGhlIGV4cGVyaW1lbnRhbCBzZXR1cCkgd2UgbWlnaHQgaGF2ZSB0aG91c2FuZHMgb2Ygc3RhdGlzdGljYWxseS1zaWduaWZpY2FudCByZXN1bHRzLCB3aGljaCBuby1vbmUgaGFzIHRoZSB0aW1lIHRvIGZvbGxvdy11cC4gQWxzbywgd2UgbWlnaHQgYmUgaW50ZXJlc3RlZCBpbiBwYXRod2F5cyAvIG1lY2hhbmlzbXMgdGhhdCBhcmUgYWx0ZXJlZCBhbmQgbm90IGp1c3QgaW5kaXZpZHVhbCBnZW5lcy4KCkluIHRoaXMgc2VjdGlvbiB3ZSBtb3ZlIHRvd2FyZHMgZGlzY292ZXJpbmcgaWYgb3VyIHJlc3VsdHMgYXJlICoqKmJpb2xvZ2ljYWxseSBzaWduaWZpY2FudCoqKi4gQXJlIHRoZSBnZW5lcyB0aGF0IHdlIGhhdmUgcGlja2VkIHN0YXRpc3RpY2FsIGZsdWtlcywgb3IgYXJlIHRoZXJlIHNvbWUgY29tbW9uYWxpdGllcy4gCgpUaGVyZSBhcmUgdHdvIGRpZmZlcmVudCBhcHByb2FjaGVzIG9uZSBtaWdodCB1c2UsIGFuZCB3ZSB3aWxsIGNvdmVyIHRoZSB0aGVvcnkgYmVoaW5kIGJvdGguIFRoZSBkaXN0aW5jdGlvbiBpcyB3aGV0aGVyIHlvdSBhcmUgaGFwcHkgdG8gdXNlIGEgaGFyZCAoYW5kIGFyYml0cmFyeSkgdGhyZXNob2xkIHRvIGlkZW50aWZ5IERFIGdlbmVzLgoKCiMjIE92ZXItcmVwcmVzZW50YXRpb24gYW5hbHlzaXMKCiJUaHJlc2hvbGQtYmFzZWQiIG1ldGhvZHMgcmVxdWlyZSBkZWZpbnRpb24gb2YgYSBzdGF0aXN0aWNhbCB0aHJlc2hvbGQgdG8gZGVmaW5lIGxpc3Qgb2YgZ2VuZXMgdG8gdGVzdCAoZS5nLiBGRFIgPCAwLjAxKS4gVGhlbiBhICpoeXBlcmdlb21ldHJpYyogdGVzdCBvciAqRmlzaGVyJ3MgRXhhY3QqIHRlc3QgZ2VuZXJhbGx5IHVzZWQuIFRoZXkgYXJlIHR5cGljYWxseSB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgcGxlbnR5IG9mIERFIGdlbmVzIGhhdmUgYmVlbiBpZGVudGlmaWVkLCBhbmQgcGVvcGxlIG9mdGVuIHVzZSBxdWl0ZSByZWxheGVkIGNyaXRlcmlhIGZvciBpZGVudGlmeWluZyBERSBnZW5lcyAoZS5nLiByYXcgcmF0aGVyIHRoYW4gYWRqdXN0ZWQgcC12YWx1ZXMgb3IgRkRSIHZhbHVlKQoKVGhlIHF1ZXN0aW9uIHdlIGFyZSBhc2tpbmcgaGVyZSBpczsKCj4gKioqIkFyZSB0aGUgbnVtYmVyIG9mIERFIGdlbmVzIGFzc29jaWF0ZWQgd2l0aCBUaGVtZSBYIHNpZ25pZmljYW50bHkgZ3JlYXRlciB0aGFuIHdoYXQgd2UgbWlnaHQgZXhwZWN0IGJ5IGNoYW5jZSBhbG9uZT8iKioqCgpXZSBjYW4gYW5zd2VyIHRoaXMgcXVlc3Rpb24gYnkga25vd2luZwoKLSB0aGUgdG90YWwgbnVtYmVyIG9mIERFIGdlbmVzCi0gdGhlIG51bWJlciBvZiBnZW5lcyBpbiB0aGUgZ2VuZSBzZXQgKHBhdGh3YXkgb3IgcHJvY2VzcykKLSB0aGUgbnVtYmVyIG9mIGdlbmVzIGluIHRoZSBnZW5lIHNldCB0aGF0IGFyZSBmb3VuZCB0byBiZSBERQotIHRoZSB0b3RhbCBudW1iZXIgb2YgdGVzdGVkIGdlbmVzIChiYWNrZ3JvdW5kKQoKVGhlIGZvcm11bGEgZm9yIEZpc2hlcnMgZXhhY3QgdGVzdCBpczsKCiQkIHAgPSBcZnJhY3tcYmlub217YSArIGJ9e2F9XGJpbm9te2MgK2R9e2N9fXtcYmlub217bn17YSArY319ID0gXGZyYWN7KGErYikhKGMrZCkhKGErYykhKGIrZCkhfXthIWIhYyFkIW4hfSAkJAoKd2l0aDotCgp8ICAgICAgICAgICAgICB8IGlzIERFIHwgTm90IERFIHwgUm93IFRvdGFsIHwKfC0tLS0tLS0tLS0tLS0gfCAtLS0tLS18LS0tLS0tLS18LS0tLS0tLS0tLS18CnwgSW4gR2VuZSBTZXQgICB8IGEgICAgIHwgYiAgICAgIHwgYSArIGIgICAgIHwKfCBOb3QgaW4gR2VuZSBTZXQgIHwgYyAgICAgfCBkICAgICAgfCBjICsgZCAgICAgfAp8IENvbHVtbiBUb3RhbCAgICB8ICBhICsgYyB8IGIgKyBkICB8IGEgKyBiICsgYyArIGQgPSBuIHwKCgpJbiB0aGlzIGZpcnN0IHRlc3QsIG91ciBnZW5lcyB3aWxsIGJlIGdyb3VwZWQgdG9nZXRoZXIgYWNjb3JkaW5nIHRvIHRoZWlyIEdlbmUgT250b2xvZ3kgKEdPKSB0ZXJtczotIGh0dHA6Ly93d3cuZ2VuZW9udG9sb2d5Lm9yZy8KCgojIyBVc2luZyBHT3JpbGxhCgpUaGVyZSBhcmUgc2V2ZXJhbCBwb3B1bGFyIG9ubGluZSB0b29scyBmb3IgcGVyZm9ybWluZyBlbnJpY2htZW50IGFuYWx5c2lzCgpXZSB3aWxsIGJlIHVzaW5nIHRoZSBvbmxpbmUgdG9vbCBbR09yaWxsYV0oaHR0cDovL2NibC1nb3JpbGxhLmNzLnRlY2huaW9uLmFjLmlsLykgdG8gcGVyZm9ybSB0aGUgcGF0aHdheXMgYW5hbHlzaXMgYXMgaXQgaXMgcGFydGljdWxhcmx5IHN0cmFpZ2h0Zm9yd2FyZC4gSXQgaGFzIHR3byBtb2RlczsgdGhlIGZpcnN0IG9mIHdoaWNoIGFjY2VwdHMgYSBsaXN0IG9mICpiYWNrZ3JvdW5kKiBhbmQgKnRhcmdldCogZ2VuZXMuIAoKMS4gR28gdG8gaHR0cDovL2NibC1nb3JpbGxhLmNzLnRlY2huaW9uLmFjLmlsLwoyLiBDaG9vc2UgT3JnYW5pc206IGBIb21vIFNhcGllbnNgCjMuIENob29zZSBydW5uaW5nIG1vZGU6IGBUd28gdW5yYW5rZWQgbGlzdHMgb2YgZ2VuZXNgCjQuIFBhc3RlIHRoZSBnZW5lIHN5bWJvbHMgY29ycmVzcG9uZGluZyB0byBERSBnZW5lcyBpbiAqU1c5NDg6IElUUkFDT05BWk9MRSB2cyBETVNPKiBpbnRvIHRoZSBUYXJnZXQgc2V0LgogICsgKipUaGUgc2hvcnRjdXQgQ1RSTCArIFNQQUNFIHdpbGwgbGV0IHlvdSBzZWxlY3QgYW4gZW50aXJlIGNvbHVtbioqCjUuIFBhc3RlIHRoZSBnZW5lIHN5bWJvbHMgZnJvbSB0aGUgQmFja2dyb3VuZCBzZXQgaW50byB0aGUgb3RoZXIgYm94LiBUaGlzIHNob3VsZCBiZSB0aGUgbmFtZXMgb2YgYWxsIGdlbmVzIHByZXNlbnQgaW4gdGhlIEJhY2tncm91bmQgZmlsZS4gaS5lLiBhbGwgZ2VuZXMgdGhhdCB3ZXJlIHRlc3RlZC4KNi4gQ2hvb3NlIGFuIE9udG9sb2d5OiBgUHJvY2Vzc2AKNy4gVW5kZXIgYWR2YW5jZWQgb3B0aW9ucywgdGljayAqKk91dHB1dCByZXN1bHRzIGluIE1pY3Jvc29mdCBFeGNlbCBmb3JtYXQqKgo4LiBgU2VhcmNoIEVucmljaGVkIEdPIHRlcm1zYAoKWW91IHNob3VsZCBiZSBwcmVzZW50ZWQgd2l0aCBhIGdyYXBoIG9mIGVucmljaGVkIEdPIHRlcm1zIHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0ZXJtcy4gRWFjaCBHTyB0ZXJtIGlzIGNvbG91cmVkIGFjY29yZGluZyB0byBpdHMgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlLgoKQmVsb3cgdGhlIGZpZ3VyZSBpcyB0aGUgcmVzdWx0cyB0YWJsZS4gVGhpcyBsaW5rcyB0byBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggR08gdGVybSwgYW5kIGxpc3RzIGVhY2ggZ2VuZSBpbiB0aGUgY2F0ZWdvcnkgdGhhdCB3YXMgZm91bmQgaW4geW91ciBsaXN0LiBUaGUgZW5yaWNobWVudCBjb2x1bW4gZ2l2ZXMgNCBudW1iZXJzIHRoYXQgYXJlIHVzZWQgdG8gZGV0ZXJtaW5lIGVucmljaG1lbnQgKHNpbWlsYXIgdG8gdGhlIEZpc2hlciBleGFjdCB0ZXN0IHdlIHNhdyBlYXJsaWVyKQoKLSBOLCB0b3RhbCBudW1iZXIgb2YgZ2VuZXMgKHNob3VsZCBiZSB0aGUgc2FtZSBpbiBhbGwgcm93cykKLSBCLCB0b3RhbCBudW1iZXIgb2YgZ2VuZXMgYW5ub3RhdGVkIHdpdGggdGhlIEdPIHRlcm0KLSBuLCB0b3RhbCBudW1iZXIgb2YgZ2VuZXMgdGhhdCB3ZXJlIGZvdW5kIGluIHRoZSBsaXN0IHlvdSB1cGxvYWRlZCAoc2FtZSBmb3IgYWxsIHJvd3MpCi0gYiwgbnVtYmVyIG9mIGdlbmVzIGluIHRoZSBsaXN0IHlvdSB1cGxvYWRlZCB0aGF0IGludGVyc2VjdCB3aXRoIHRoaXMgR08gdGVybQoKPGRpdiBjbGFzcz0iZXhlcmNpc2UiPgoqKkV4ZXJjaXNlOioqIFJlcGVhdCB0aGUgR09yaWxsYSB0byBmaW5kIGVucmljaGVkIHBhdGh3YXlzIGluIHRoZSBIVDU1OiBJVFJBQ09OQVpPTEUgdnMgRE1TTyBhbmFseXNpcy4gV2hhdCBkbyB5b3Ugbm90aWNlPwo8L2Rpdj4KCgojIyBUaHJlc2hvbGQtZnJlZSBhbmFseXNpcwoKVGhpcyB0eXBlIG9mIGFuYWx5c2lzIGlzIHBvcHVsYXIgZm9yIGRhdGFzZXRzIHdoZXJlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzIGRvZXMgbm90IHJldmVhbCBtYW55IGdlbmVzIHRoYXQgYXJlIGRpZmZlcmVudGlhbGx5LWV4cHJlc3NlZCBvbiB0aGVpciBvd24uIEluc3RlYWQsIGl0IHNlZWtzIHRvIGlkZW50aWZ5IGdlbmVzIHRoYXQgYXMgYSBncm91cCBoYXZlIGEgdGVuZGFuY3kgdG8gYmUgbmVhciB0aGUgZXh0cmVtZXMgb2YgdGhlIGxvZy1mb2xkIGNoYW5nZXMuIFRoZSByZXN1bHRzIGFyZSB0eXBpY2FsbHkgcHJlc2VudGVkIGluIHRoZSBmb2xsb3dpbmcgd2F5LgoKIVtdKG1lZGlhL292ZXJleHByZXNzZWQtZ3NlYS5wbmcpCgpBcyBzdWNoLCBpdCBkb2VzIG5vdCByZWx5IG9uIGhhdmluZyB0byBpbXBvc2UgYXJiaXRyYXJ5IGN1dC1vZmZzIG9uIHRoZSBkYXRhLiBJbnN0ZWFkLCB3ZSBuZWVkIHRvIHByb3ZpZGUgYSBtZWFzdXJlIG9mIHRoZSBpbXBvcnRhbmNlIG9mIGVhY2ggZ2VuZSBzdWNoIGFzIGl0J3MgZm9sZC1jaGFuZ2UuIFRoZXNlIGFyZSB0aGVuIHVzZWQgdGhlIHJhbmsgdGhlIGdlbmVzLgoKVGhlIEJyb2FkIGluc3RpdHV0ZSBoYXMgbWFkZSB0aGlzIGFuYWx5c2lzIG1ldGhvZCBwb3B1bGFyIGFuZCBwcm92aWRlcyBbYSB2ZXJzaW9uIG9mIEdTRUFdKGh0dHA6Ly9zb2Z0d2FyZS5icm9hZGluc3RpdHV0ZS5vcmcvZ3NlYS9pbmRleC5qc3ApIHRoYXQgY2FuIGJlIHJ1biB2aWEgYSBqYXZhIGFwcGxpY2F0aW9uLiBIb3dldmVyLCB0aGUgYXBwbGljYXRpb24gY2FuIGJlIGEgYml0IGZpZGRseSB0byBydW4sIHNvIHdlIHdpbGwgdXNlIHRoZSBHZW5lVHJhaWwgd2Vic2l0ZSBpbnN0ZWFkCgotIE9wZW4gdGhlIGZpbGUgYGJhY2tncm91bmQuY3N2YCBpbiBFeGNlbCBhbmQgZGVsZXRlIGFsbCBjb2x1bW5zIGV4Y2VwdCB0aGUgYFNZTUJPTGAgYW5kIGBJVFJBYCBjb2x1bW4uCjxpbWcgc3JjPSJtZWRpYS9HZW5lVHJhaWxfcHJlcC5wbmciLz4KLSBHbyB0byB0aGUgR2VuZVRyYWlsIHdlYnNpdGUsIGFuZCBzZWxlY3QgVHJhbnNjcmlwdG9taWNzIGZyb20gdGhlIGZyb250IHBhZ2UKLSBTZWxlY3QgdGhlICoqUGFzdGUgdGhlIGNvbnRlbnQgb2YgYSB0ZXh0IGZpbGUgaW4gYSB0YWJ1bGFyIGZvcm1hdCBvcHRpb24qKiBhbmQgdGhlIGNvbnRlbnRzIG9mIHlvdXIgbW9kaWZpZWQgZXhjZWwgZmlsZSBpbnRvIHRoZSBib3guICoqRG8gbm90IHBhc3RlIHRoZSBjb2x1bW4gaGVhZGluZ3MqKgotIENsaWNrIFVwbG9hZAoKSG9wZWZ1bGx5IGl0IHNob3VsZCByZWNvZ25pc2UgeW91ciBpbnB1dCB3aXRob3V0IGFueSBlcnJvcnMsIGFuZCBvbiB0aGUgbmV4dCBzY3JlZW4gdGhlICoqU2V0LWxldmVsIHN0YXRpc3RpYyoqIHNob3VsZCBiZSBhdXRvbWF0aWNhbGx5IHNldCB0byAqKkdTRUEqKgoKPGRpdiBjbGFzcz0id2FybmluZyI+CklmIHlvdXIgZGF0YSBkb2VzIG5vdCBnZXQgdXBsb2FkZWQsIGRvdWJsZS1jaGVjayB0aGF0IHRoZSBjb2x1bW4gaGVhZGluZyAqKklUUkEqKiBoYXMgbm90IGJlZW4gcGFzdGVkIGludG8gdGhlIHRleHQgYm94CjwvZGl2PgoKVG8gbWFrZSB0aGUgYW5hbHlzaXMgcnVuIGZhc3QsIHlvdSBjYW4gZGUtc2VsZWN0IHRoZSBHTyBwYXRod2F5cyAoYmlvbG9naWNhbCBwcm9jZXNzZXMsIG1vbGVjdWxhciBmdW5jdGlvbiBhbmQgY2VsbHVsYXIgY29tcGFydG1lbnQpCgo=